Skip to content

Commit

Permalink
Automatic black formatting for python examples (#477)
Browse files Browse the repository at this point in the history
* black extension

* clean

* Add a few extensions

* script

* append to script

* write files

* update

* update

* update

* remove files

* append

* update

* retour bons fichiers

* up

* viewof

* reorder

* update
  • Loading branch information
linogaliana committed Dec 19, 2023
1 parent 3fba612 commit e52cc8a
Show file tree
Hide file tree
Showing 14 changed files with 526 additions and 6 deletions.
1 change: 1 addition & 0 deletions .github/workflows/netlify-test.yaml
Expand Up @@ -23,6 +23,7 @@ jobs:
run: |
quarto --version
git diff --name-only origin/master origin/${GITHUB_HEAD_REF} >> diff
python build/append_environment.py
python build/tweak_render.py
cat _quarto.yml
quarto render --to html
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/prod.yml
Expand Up @@ -5,7 +5,6 @@ on:
branches:
- main
- master
- docker

jobs:
docker:
Expand Down Expand Up @@ -57,6 +56,7 @@ jobs:
run: git config --global --add safe.directory /__w/python-datascientist/python-datascientist
- name: Render website
run: |
python build/append_environment.py
quarto render --to html
- name: Publish to Pages
if: github.ref == 'refs/heads/master'
Expand Down
8 changes: 8 additions & 0 deletions _extensions/linogaliana/pip-freeze/_extension.yml
@@ -0,0 +1,8 @@
title: pip-freeze
author: Lino Galiana
version: 0.1.0
quarto-required: ">=1.3.0"
contributes:
shortcodes:
- pip-freeze.lua

28 changes: 28 additions & 0 deletions _extensions/linogaliana/pip-freeze/pip-freeze.lua
@@ -0,0 +1,28 @@
-- run pip and read its output
local function pip(command)
local p = io.popen("pip " .. command)
local output = ""
if p ~= nil then
output = p:read('*a') -- Use '*a' to read the entire output
p:close()
end
return output
end

return {
["pip-freeze"] = function(args, kwargs)
local raw_cmd = "list"
local piplist = pip(raw_cmd)

-- return as string
if piplist ~= nil and piplist ~= "" then
return pandoc.read(
"<div class = \"pip-freeze\">\n" ..
piplist .. "</div>"
).blocks
else
return "nothing returned"
--return pandoc.Null()
end
end
}
8 changes: 8 additions & 0 deletions _extensions/linogaliana/rev-history/_extension.yml
@@ -0,0 +1,8 @@
title: rev-history
author: Lino Galiana
version: 0.1.0
quarto-required: ">=1.3.0"
contributes:
shortcodes:
- rev-history.lua

45 changes: 45 additions & 0 deletions _extensions/linogaliana/rev-history/rev-history.lua
@@ -0,0 +1,45 @@
-- run git and read its output
local function git(command)
local p = io.popen("git " .. command)
local output = ""
if p ~= nil then
output = p:read('*all')
p:close()
end
return output
end

local github_repo = "https://github.com/linogaliana/python-datascientist/commit"

-- return a table containing shortcode definitions
-- defining shortcodes this way allows us to create helper
-- functions that are not themselves considered shortcodes
return {
["rev-history"] = function(args, kwargs)
local header = "<thead><tr>" ..
"<th>SHA</th>" ..
"<th>Date</th>" ..
"<th>Author</th>" ..
"<th>Description</th>" ..
"</tr></thead>\n"
local divider = "<tbody>"

-- run the command
local filename = quarto.doc.input_file
local raw_cmd = "log --follow --pretty=format:\"<tr><td>[%h]($repo/%h)</td><td>%ad</td><td>%an</td><td>%s</td></tr>\" --date=format:'%Y-%m-%d %H:%M:%S' -- "
local raw_cmd_sub = string.gsub(raw_cmd, "$repo", github_repo)
local cmd = raw_cmd_sub .. filename
local tags = git(cmd)

-- return as string
if tags ~= nil then
return pandoc.read(
"<table class='commit-table' border='1'>" ..
header .. divider .. tags ..
"</tbody></table>\n\n"
).blocks
else
return pandoc.Null()
end
end
}
8 changes: 8 additions & 0 deletions _extensions/shafayetShafee/black-formatter/_extension.yml
@@ -0,0 +1,8 @@
title: Black-formatter
author: Shafayet Khan Shafee
version: 1.1.1
quarto-required: ">=1.2.0"
contributes:
filters:
- black-formatter.lua

99 changes: 99 additions & 0 deletions _extensions/shafayetShafee/black-formatter/black-formatter.lua
@@ -0,0 +1,99 @@
--[[
MIT License
Copyright (c) 2023 Shafayet Khan Shafee
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]]--


local function isEmpty(s)
return s == nil or s == ''
end


local function add_codeblock_label(label)
local labeller = {
-- Add id for code block using the id from div.cell
CodeBlock = function(cb)
if cb.classes:includes('python') then
cb.identifier = label
return cb
end
end
}
return labeller
end


local function label_codeblock()
local labelled_cb = {
Div = function(el)
if el.classes:includes("cell") then
local label = el.identifier
return el:walk(add_codeblock_label(label))
end
end
}
return labelled_cb
end


local function black_format()
local black_formatter = {
CodeBlock = function(cb)
if cb.classes:includes('python') then
local randName = string.char(
math.random(97,122), math.random(97,122),
math.random(97,122), math.random(97,122),
math.random(97,122), math.random(97,122)
)

local label = cb.identifier
local name

if isEmpty(label) then
name = "_" .. randName .. "_black_formatted.py"
else
name = "_" .. label .. "_black_formatted.py"
end

local f = io.open(name, 'w+b')
f:write(cb.text)
f:close()
local formatted = io.popen("python -m black " .. name)
formatted:close()
local formatted_file = io.open(name, 'r')
local formatted_content = formatted_file:read("*all")
formatted_file:close()
os.remove(name)
cb.text = formatted_content
return cb
end
end
}
return black_formatter
end


function Pandoc(doc)
local doc = doc:walk(label_codeblock())
return doc:walk(black_format())
end

4 changes: 3 additions & 1 deletion _quarto.yml
Expand Up @@ -192,7 +192,9 @@ website:


filters:
- lightbox
- lightbox
- black-formatter

lightbox: auto

format:
Expand Down
113 changes: 113 additions & 0 deletions build/_handle_git_history.qmd
@@ -0,0 +1,113 @@
```{ojs}
//| echo: false
Inputs.table(
table_commit,
{
format: {
SHA: x => md`[${x}](${github_repo}/commit/${x})`,
Description: x => md`${replacePullRequestPattern(x, github_repo)}`,
/*Date: x => x.toLocaleString("fr", {
"month": "numeric",
"day": "numeric",
"year": "numeric"
})
*/
}
}
)
```

```{ojs}
//| echo: false
Plot.plot({
marks: [
Plot.ruleY([0], {stroke: "royalblue"}),
Plot.dot(
table_commit,
Plot.pointerX({x: (d) => new Date(d.date), y: 0, stroke: "red"})),
Plot.dot(table_commit, {x: (d) => new Date(d.Date), y: 0, fill: "royalblue"})
]
})
```


```{ojs}
//| echo: false
function replacePullRequestPattern(inputString, githubRepo) {
// Use a regular expression to match the pattern #digit
var pattern = /#(\d+)/g;
// Replace the pattern with ${github_repo}/pull/#digit
var replacedString = inputString.replace(pattern, '[#$1](' + githubRepo + '/pull/$1)');
return replacedString;
}
```


```{ojs}
//| echo: false
github_repo = "https://github.com/linogaliana/python-datascientist"
```

```{ojs}
//| echo: false
table_commit = {
// Get the HTML table by its class name
var table = document.querySelector('.commit-table');
// Check if the table exists
if (table) {
// Initialize an array to store the table data
var dataArray = [];
// Extract headers from the first row
var headers = [];
for (var i = 0; i < table.rows[0].cells.length; i++) {
headers.push(table.rows[0].cells[i].textContent.trim());
}
// Iterate through the rows, starting from the second row
for (var i = 1; i < table.rows.length; i++) {
var row = table.rows[i];
var rowData = {};
// Iterate through the cells in the row
for (var j = 0; j < row.cells.length; j++) {
// Use headers as keys and cell content as values
rowData[headers[j]] = row.cells[j].textContent.trim();
}
// Push the rowData object to the dataArray
dataArray.push(rowData);
}
}
return dataArray
}
```


```{ojs}
//| echo: false
//| output: false
// Get the element with class 'git-details'
{
var gitDetails = document.querySelector('.git-details');
// Check if the element exists
if (gitDetails) {
// Hide the element
gitDetails.style.display = 'none';
}
}
```

```{ojs}
//| echo: false
Plot = require('@observablehq/plot@0.6.12/dist/plot.umd.min.js')
```

0 comments on commit e52cc8a

Please sign in to comment.