diff --git a/_layouts/distill.liquid b/_layouts/distill.liquid index 500077d78109..e5a8bc412d1e 100644 --- a/_layouts/distill.liquid +++ b/_layouts/distill.liquid @@ -14,6 +14,19 @@ {% endif %} {% include scripts/jquery.liquid %} {% include scripts/mathjax.liquid %} + {% include scripts/mermaid.liquid %} + {% include scripts/diff2html.liquid %} + {% include scripts/leaflet.liquid %} + {% include scripts/chartjs.liquid %} + {% include scripts/echarts.liquid %} + {% include scripts/vega.liquid %} + {% include scripts/tikzjax.liquid %} + {% include scripts/typograms.liquid %} + {% include scripts/misc.liquid %} + {% comment %} + misc.liquid loads interactive features like the code copy button to prevent dynamic elements from displaying incorrectly at the end of the article. + {% endcomment %} + diff --git a/_posts/2018-12-22-distill.md b/_posts/2018-12-22-distill.md index 6fa2e8d8002b..dbf1ec587661 100644 --- a/_posts/2018-12-22-distill.md +++ b/_posts/2018-12-22-distill.md @@ -6,6 +6,17 @@ tags: distill formatting giscus_comments: true date: 2021-05-22 featured: true +mermaid: + enabled: true + zoomable: true +code_diff: true +map: true +chart: + chartjs: true + echarts: true + vega_lite: true +tikzjax: true +typograms: true authors: - name: Albert Einstein @@ -39,6 +50,12 @@ toc: - name: Footnotes - name: Code Blocks - name: Interactive Plots + - name: Mermaid + - name: Diff2Html + - name: Leaflet + - name: Chartjs, Echarts and Vega-Lite + - name: TikZ + - name: Typograms - name: Layouts - name: Other Typography? @@ -67,6 +84,8 @@ This theme supports rendering beautiful math in inline and display modes using [ You just need to surround your math expression with `$$`, like `$$ E = mc^2 $$`. If you leave it inside a paragraph, it will produce an inline expression, just like $$ E = mc^2 $$. +In fact, you can also use a single dollar sign `$` to create inline formulas, such as `$ E = mc^2 $`, which will render as $ E = mc^2 $. This approach provides the same effect during TeX-based compilation, but visually it appears slightly less bold compared to double-dollar signs `$$`, making it blend more naturally with surrounding text. + To use display mode, again surround your expression with `$$` and place it as a separate paragraph. Here is an example: @@ -167,6 +186,1102 @@ Additional details, where math $$ 2x - 1 $$ and `code` is rendered correctly. --- +## Mermaid + +This theme supports creating diagrams directly in markdown using [Mermaid](https://mermaid.js.org/). Mermaid enables users to render flowcharts, sequence diagrams, class diagrams, Gantt charts, and more. Simply embed the diagram syntax within a mermaid code block. + +To create a Gantt chart, you can use the following syntax: + +````markdown +```mermaid +gantt + dateFormat YYYY-MM-DD + title A Gantt Diagram + + section Section + Task A :a1, 2025-01-01, 30d + Task B :after a1, 20d + Task C :2025-01-10, 12d +``` +```` + +And here’s how it will be rendered: + +```mermaid +gantt + dateFormat YYYY-MM-DD + title A Gantt Diagram + + section Section + Task A :a1, 2025-01-01, 30d + Task B :after a1, 20d + Task C :2025-01-10, 12d +``` + +Similarly, you can also use it to create beautiful class diagrams: + +```` +```mermaid +classDiagram +direction LR + class Animal { + +String species + +int age + +makeSound() + } + class Dog { + +String breed + +bark() + } + class Cat { + +String color + +meow() + } + class Bird { + +String wingSpan + +fly() + } + class Owner { + +String name + +int age + +adoptAnimal(Animal animal) + } + + Animal <|-- Dog + Animal <|-- Cat + Animal <|-- Bird + Owner "1" --> "0..*" Animal + + Dog : +fetch() + Cat : +purr() + Bird : +sing() +``` +```` + +It will be presented as: + +```mermaid +classDiagram +direction LR + class Animal { + +String species + +int age + +makeSound() + } + class Dog { + +String breed + +bark() + } + class Cat { + +String color + +meow() + } + class Bird { + +String wingSpan + +fly() + } + class Owner { + +String name + +int age + +adoptAnimal(Animal animal) + } + + Animal <|-- Dog + Animal <|-- Cat + Animal <|-- Bird + Owner "1" --> "0..*" Animal + + Dog : +fetch() + Cat : +purr() + Bird : +sing() +``` + +With Mermaid, you can easily add clear and dynamic diagrams to enhance your blog content. + +--- + +## Diff2Html + +This theme also supports integrating [Diff2Html](https://github.com/rtfpessoa/diff2html), a tool that beautifully renders code differences (diffs) directly in markdown. Diff2Html is ideal for showcasing code changes, allowing you to clearly present additions, deletions, and modifications. It’s perfect for code reviews, documentation, and tutorials where step-by-step code changes need to be highlighted—you can even introduce changes across multiple files at once. + +````markdown +```diff2html +diff --git a/utils/mathUtils.js b/utils/mathUtils.js +index 3b5f3d1..c7f9b2e 100644 +--- a/utils/mathUtils.js ++++ b/utils/mathUtils.js +@@ -1,8 +1,12 @@ +-// Basic math utilities ++// Extended math utilities with additional functions + +-export function calculateArea(radius) { +- const PI = 3.14159; ++export function calculateCircleMetrics(radius) { ++ const PI = Math.PI; + const area = PI * radius ** 2; ++ const circumference = 2 * PI * radius; ++ ++ if (!isValidRadius(radius)) throw new Error("Invalid radius"); ++ + return { area, circumference }; + } + +-export function validateRadius(radius) { ++export function isValidRadius(radius) { + return typeof radius === 'number' && radius > 0; + } + +diff --git a/main.js b/main.js +index 5f6a9c3..b7d4e8f 100644 +--- a/main.js ++++ b/main.js +@@ -2,9 +2,12 @@ + import { calculateCircleMetrics } from './utils/mathUtils'; + +-function displayCircleMetrics(radius) { +- const { area } = calculateCircleMetrics(radius); ++function displayCircleMetrics(radius) { ++ const { area, circumference } = calculateCircleMetrics(radius); + console.log(`Area: ${area}`); ++ console.log(`Circumference: ${circumference}`); + } + +-displayCircleMetrics(5); ++try { ++ displayCircleMetrics(5); ++} catch (error) { ++ console.error("Error:", error.message); ++} +``` +```` + +Here’s how it will look when rendered with Diff2Html: + +```diff2html +diff --git a/utils/mathUtils.js b/utils/mathUtils.js +index 3b5f3d1..c7f9b2e 100644 +--- a/utils/mathUtils.js ++++ b/utils/mathUtils.js +@@ -1,8 +1,12 @@ +-// Basic math utilities ++// Extended math utilities with additional functions + +-export function calculateArea(radius) { +- const PI = 3.14159; ++export function calculateCircleMetrics(radius) { ++ const PI = Math.PI; + const area = PI * radius ** 2; ++ const circumference = 2 * PI * radius; ++ ++ if (!isValidRadius(radius)) throw new Error("Invalid radius"); ++ + return { area, circumference }; + } + +-export function validateRadius(radius) { ++export function isValidRadius(radius) { + return typeof radius === 'number' && radius > 0; + } + +diff --git a/main.js b/main.js +index 5f6a9c3..b7d4e8f 100644 +--- a/main.js ++++ b/main.js +@@ -2,9 +2,12 @@ + import { calculateCircleMetrics } from './utils/mathUtils'; + +-function displayCircleMetrics(radius) { +- const { area } = calculateCircleMetrics(radius); ++function displayCircleMetrics(radius) { ++ const { area, circumference } = calculateCircleMetrics(radius); + console.log(`Area: ${area}`); ++ console.log(`Circumference: ${circumference}`); + } + +-displayCircleMetrics(5); ++try { ++ displayCircleMetrics(5); ++} catch (error) { ++ console.error("Error:", error.message); ++} +``` + +--- + +## Leaflet + +[Leaflet](https://leafletjs.com/) is created by Ukrainian software engineer [Volodymyr Agafonkin](https://agafonkin.com/), allowing interactive maps to be embedded in webpages. With support for [GeoJSON data](https://geojson.org/), Leaflet allows you to highlight specific regions, making it easy to visualize geographical information in detail. + +You can use the following code to load map information on [OpenStreetMap](https://www.openstreetmap.org/): + +````markdown +```geojson +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "name": "Crimea", + "popupContent": "Occupied Crimea" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 33.9, + 45.3 + ], + [ + 36.5, + 45.3 + ], + [ + 36.5, + 44.4 + ], + [ + 33.9, + 44.4 + ], + [ + 33.9, + 45.3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "name": "Donetsk", + "popupContent": "Occupied Donetsk" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 37.5, + 48.5 + ], + [ + 39.5, + 48.5 + ], + [ + 39.5, + 47.5 + ], + [ + 37.5, + 47.5 + ], + [ + 37.5, + 48.5 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "name": "Luhansk", + "popupContent": "Occupied Luhansk" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 38.5, + 49.5 + ], + [ + 40.5, + 49.5 + ], + [ + 40.5, + 48.5 + ], + [ + 38.5, + 48.5 + ], + [ + 38.5, + 49.5 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "name": "Kherson", + "popupContent": "Occupied Kherson" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 32.3, + 47.3 + ], + [ + 34.3, + 47.3 + ], + [ + 34.3, + 46.3 + ], + [ + 32.3, + 46.3 + ], + [ + 32.3, + 47.3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "name": "Zaporizhzhia", + "popupContent": "Occupied Zaporizhzhia" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 34.3, + 48 + ], + [ + 36.3, + 48 + ], + [ + 36.3, + 47 + ], + [ + 34.3, + 47 + ], + [ + 34.3, + 48 + ] + ] + ] + } + } + ] +} +``` +```` + +The rendered map below highlights the regions of Ukraine that have been illegally occupied by Russia over the years, including Crimea and the four eastern regions: + +```geojson +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "name": "Crimea", + "popupContent": "Occupied Crimea" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 33.9, + 45.3 + ], + [ + 36.5, + 45.3 + ], + [ + 36.5, + 44.4 + ], + [ + 33.9, + 44.4 + ], + [ + 33.9, + 45.3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "name": "Donetsk", + "popupContent": "Occupied Donetsk" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 37.5, + 48.5 + ], + [ + 39.5, + 48.5 + ], + [ + 39.5, + 47.5 + ], + [ + 37.5, + 47.5 + ], + [ + 37.5, + 48.5 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "name": "Luhansk", + "popupContent": "Occupied Luhansk" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 38.5, + 49.5 + ], + [ + 40.5, + 49.5 + ], + [ + 40.5, + 48.5 + ], + [ + 38.5, + 48.5 + ], + [ + 38.5, + 49.5 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "name": "Kherson", + "popupContent": "Occupied Kherson" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 32.3, + 47.3 + ], + [ + 34.3, + 47.3 + ], + [ + 34.3, + 46.3 + ], + [ + 32.3, + 46.3 + ], + [ + 32.3, + 47.3 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "name": "Zaporizhzhia", + "popupContent": "Occupied Zaporizhzhia" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 34.3, + 48 + ], + [ + 36.3, + 48 + ], + [ + 36.3, + 47 + ], + [ + 34.3, + 47 + ], + [ + 34.3, + 48 + ] + ] + ] + } + } + ] +} +``` + +--- + +## Chartjs, Echarts and Vega-Lite + +[Chart.js](https://www.chartjs.org/) is a versatile JavaScript library for creating responsive and interactive charts. Supporting multiple chart types like bar, line, pie, and radar, it’s an ideal tool for visualizing data directly in webpages. + +Here’s an example of a JSON-style configuration that creates a bar chart in Chart.js: + +```` +```chartjs +{ + "type": "bar", + "data": { + "labels": ["2017", "2018", "2019", "2020", "2021"], + "datasets": [ + { + "label": "Population (millions)", + "data": [12, 15, 13, 14, 16], + "backgroundColor": "rgba(54, 162, 235, 0.6)", + "borderColor": "rgba(54, 162, 235, 1)", + "borderWidth": 1 + } + ] + }, + "options": { + "scales": { + "y": { + "beginAtZero": true + } + } + } +} +``` +```` + +The rendered bar chart illustrates population data from 2017 to 2021: + +```chartjs +{ + "type": "bar", + "data": { + "labels": ["2017", "2018", "2019", "2020", "2021"], + "datasets": [ + { + "label": "Population (millions)", + "data": [12, 15, 13, 14, 16], + "backgroundColor": "rgba(54, 162, 235, 0.6)", + "borderColor": "rgba(54, 162, 235, 1)", + "borderWidth": 1 + } + ] + }, + "options": { + "scales": { + "y": { + "beginAtZero": true + } + } + } +} +``` + +--- + +[ECharts](https://echarts.apache.org/) is a powerful visualization library from [Apache](https://www.apache.org/) that supports a wide range of interactive charts, including more advanced types such as scatter plots, heatmaps, and geographic maps. + +The following JSON configuration creates a visually enhanced line chart that displays monthly sales data for two products. + +```` +```echarts +{ + "title": { + "text": "Monthly Sales Comparison", + "left": "center" + }, + "tooltip": { + "trigger": "axis", + "backgroundColor": "rgba(50, 50, 50, 0.7)", + "borderColor": "#777", + "borderWidth": 1, + "textStyle": { + "color": "#fff" + } + }, + "legend": { + "data": ["Product A", "Product B"], + "top": "10%" + }, + "xAxis": { + "type": "category", + "data": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], + "axisLine": { + "lineStyle": { + "color": "#888" + } + } + }, + "yAxis": { + "type": "value", + "axisLine": { + "lineStyle": { + "color": "#888" + } + }, + "splitLine": { + "lineStyle": { + "type": "dashed" + } + } + }, + "series": [ + { + "name": "Product A", + "type": "line", + "smooth": true, + "data": [820, 932, 901, 934, 1290, 1330, 1320, 1400, 1450, 1500, 1600, 1650], + "itemStyle": { + "color": "#5470C6" + }, + "lineStyle": { + "width": 3 + }, + "areaStyle": { + "color": { + "type": "linear", + "x": 0, + "y": 0, + "x2": 0, + "y2": 1, + "colorStops": [ + { "offset": 0, "color": "rgba(84, 112, 198, 0.5)" }, + { "offset": 1, "color": "rgba(84, 112, 198, 0)" } + ] + } + }, + "emphasis": { + "focus": "series" + } + }, + { + "name": "Product B", + "type": "line", + "smooth": true, + "data": [620, 732, 701, 734, 1090, 1130, 1120, 1200, 1250, 1300, 1400, 1450], + "itemStyle": { + "color": "#91CC75" + }, + "lineStyle": { + "width": 3 + }, + "areaStyle": { + "color": { + "type": "linear", + "x": 0, + "y": 0, + "x2": 0, + "y2": 1, + "colorStops": [ + { "offset": 0, "color": "rgba(145, 204, 117, 0.5)" }, + { "offset": 1, "color": "rgba(145, 204, 117, 0)" } + ] + } + }, + "emphasis": { + "focus": "series" + } + } + ] +} +``` +```` + +The rendered output is shown below, and you can also interact with it using your mouse: + +```echarts +{ + "title": { + "text": "Monthly Sales Comparison", + "left": "center" + }, + "tooltip": { + "trigger": "axis", + "backgroundColor": "rgba(50, 50, 50, 0.7)", + "borderColor": "#777", + "borderWidth": 1, + "textStyle": { + "color": "#fff" + } + }, + "legend": { + "data": ["Product A", "Product B"], + "top": "10%" + }, + "xAxis": { + "type": "category", + "data": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], + "axisLine": { + "lineStyle": { + "color": "#888" + } + } + }, + "yAxis": { + "type": "value", + "axisLine": { + "lineStyle": { + "color": "#888" + } + }, + "splitLine": { + "lineStyle": { + "type": "dashed" + } + } + }, + "series": [ + { + "name": "Product A", + "type": "line", + "smooth": true, + "data": [820, 932, 901, 934, 1290, 1330, 1320, 1400, 1450, 1500, 1600, 1650], + "itemStyle": { + "color": "#5470C6" + }, + "lineStyle": { + "width": 3 + }, + "areaStyle": { + "color": { + "type": "linear", + "x": 0, + "y": 0, + "x2": 0, + "y2": 1, + "colorStops": [ + { "offset": 0, "color": "rgba(84, 112, 198, 0.5)" }, + { "offset": 1, "color": "rgba(84, 112, 198, 0)" } + ] + } + }, + "emphasis": { + "focus": "series" + } + }, + { + "name": "Product B", + "type": "line", + "smooth": true, + "data": [620, 732, 701, 734, 1090, 1130, 1120, 1200, 1250, 1300, 1400, 1450], + "itemStyle": { + "color": "#91CC75" + }, + "lineStyle": { + "width": 3 + }, + "areaStyle": { + "color": { + "type": "linear", + "x": 0, + "y": 0, + "x2": 0, + "y2": 1, + "colorStops": [ + { "offset": 0, "color": "rgba(145, 204, 117, 0.5)" }, + { "offset": 1, "color": "rgba(145, 204, 117, 0)" } + ] + } + }, + "emphasis": { + "focus": "series" + } + } + ] +} +``` + +--- + +[Vega-Lite](https://vega.github.io/vega-lite/) is a declarative visualization grammar that allows users to create, share, and customize a wide range of interactive data visualizations. The following JSON configuration generates a straightforward bar chart: + +```` +```vega_lite +{ + "$schema": "https://vega.github.io/schema/vega/v5.json", + "width": 400, + "height": 200, + "padding": 5, + + "data": [ + { + "name": "table", + "values": [ + {"category": "A", "value": 28}, + {"category": "B", "value": 55}, + {"category": "C", "value": 43}, + {"category": "D", "value": 91}, + {"category": "E", "value": 81}, + {"category": "F", "value": 53}, + {"category": "G", "value": 19}, + {"category": "H", "value": 87} + ] + } + ], + + "scales": [ + { + "name": "xscale", + "type": "band", + "domain": {"data": "table", "field": "category"}, + "range": "width", + "padding": 0.1 + }, + { + "name": "yscale", + "type": "linear", + "domain": {"data": "table", "field": "value"}, + "nice": true, + "range": "height" + } + ], + + "axes": [ + {"orient": "bottom", "scale": "xscale"}, + {"orient": "left", "scale": "yscale"} + ], + + "marks": [ + { + "type": "rect", + "from": {"data": "table"}, + "encode": { + "enter": { + "x": {"scale": "xscale", "field": "category"}, + "width": {"scale": "xscale", "band": 0.8}, + "y": {"scale": "yscale", "field": "value"}, + "y2": {"scale": "yscale", "value": 0}, + "fill": {"value": "steelblue"} + }, + "update": { + "fillOpacity": {"value": 1} + }, + "hover": { + "fill": {"value": "orange"} + } + } + } + ] +} +``` +```` + +The rendered output shows a clean and simple bar chart with a hover effect: + +```vega_lite +{ + "$schema": "https://vega.github.io/schema/vega/v5.json", + "width": 400, + "height": 200, + "padding": 5, + + "data": [ + { + "name": "table", + "values": [ + {"category": "A", "value": 28}, + {"category": "B", "value": 55}, + {"category": "C", "value": 43}, + {"category": "D", "value": 91}, + {"category": "E", "value": 81}, + {"category": "F", "value": 53}, + {"category": "G", "value": 19}, + {"category": "H", "value": 87} + ] + } + ], + + "scales": [ + { + "name": "xscale", + "type": "band", + "domain": {"data": "table", "field": "category"}, + "range": "width", + "padding": 0.1 + }, + { + "name": "yscale", + "type": "linear", + "domain": {"data": "table", "field": "value"}, + "nice": true, + "range": "height" + } + ], + + "axes": [ + {"orient": "bottom", "scale": "xscale"}, + {"orient": "left", "scale": "yscale"} + ], + + "marks": [ + { + "type": "rect", + "from": {"data": "table"}, + "encode": { + "enter": { + "x": {"scale": "xscale", "field": "category"}, + "width": {"scale": "xscale", "band": 0.8}, + "y": {"scale": "yscale", "field": "value"}, + "y2": {"scale": "yscale", "value": 0}, + "fill": {"value": "steelblue"} + }, + "update": { + "fillOpacity": {"value": 1} + }, + "hover": { + "fill": {"value": "orange"} + } + } + } + ] +} +``` + +--- + +## TikZ + +[TikZ](https://tikz.net/) is a powerful LaTeX-based drawing tool powered by [TikZJax](https://tikzjax.com/). You can easily port TikZ drawings from papers, posters, and notes. For example, we can use the following code to illustrate Euler’s formula $ e^{i \theta} = \cos \theta + i \sin \theta $: + +```markdown + +``` + +The rendered output is shown below, displayed as a vector graphic: + + + +--- + +## Typograms + +[Typograms](https://google.github.io/typograms/) are a way of combining text and graphics to convey information in a clear and visually engaging manner. Typograms are particularly effective for illustrating simple diagrams, charts, and concept visuals where text and graphics are closely integrated. The following example demonstrates a simple Typogram: + +```` +```typograms + ___________________ + / /| + /__________________/ | + | | | + | Distill | | + | | | + | | / + |__________________|/ +``` +```` + +The rendered output is shown below: + +```typograms + ___________________ + / /| + /__________________/ | + | | | + | Distill | | + | | | + | | / + |__________________|/ +``` + +--- + ## Layouts The main text column is referred to as the body.