« Module:Flowchart » : différence entre les versions

De Wikimedica
(Création du module avec un exemple)
 
(Retire tous les types de caractères Unicode blancs autour des noms de nœuds)
 
(27 versions intermédiaires par 2 utilisateurs non affichées)
Ligne 1 : Ligne 1 :
local p = {} --p stands for package
local p = {}


function p.hello( frame )
--[======[ Fonctions utilitaires ]======]--
    return "Hello, world!"
 
local getArgs = require("Module:Arguments").getArgs
 
--- Récupère la liste des clés d’un tableau associatif
local function get_table_keys(t)
local keys = {}
for key, _ in pairs(t) do
table.insert(keys, '"' .. key .. '"')
end
return table.concat(keys, ", ")
end
 
--- Convertit un identifiant d’objet en identifiant utilisé en syntaxe Mermaid
local function generate_id(id)
-- On utilise une version hachée de l’identifiant de chaque objet (avec un
-- algorithme de hachage faible, acceptable ici car nous n’en faisons pas
-- une utilisation cryptographique) afin de permettre l’utilisation de
-- caractères arbitraires dans le Wikicode sans poser de problèmes au
-- parseur Mermaid
return mw.hash.hashValue("md5", id)
end
 
--- Échappe les guillemets droits utilisés dans une étiquette
local function escape_quotes(label)
return string.gsub(label, '"', "#quot;")
end
 
--- Découpe une chaîne autour de la première occurrence d’un délimiteur
--- et ignore les caractères blancs autour des deux segments résultant
 
-- Liste des caractères Unicode blancs, tirée de
-- <https://en.wikipedia.org/wiki/Unicode_character_property#Whitespace>
local whitespace = mw.ustring.char(
0x9, 0xA, 0xB, 0xC, 0xD, 0x20, 0x85, 0xA0, 0x1680,
0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006,
0x2007, 0x2008, 0x2009, 0x200A, 0x2028, 0x2029, 0x202F,
0x205F, 0x3000
)
 
local function split_delimiter(s, delim)
local d_start, d_end = string.find(s, delim, 1, true)
if d_start and d_end then
local left = mw.text.trim(string.sub(s, 1, d_start - 1), whitespace)
local right = mw.text.trim(string.sub(s, d_end + 1), whitespace)
return left, right
else
return s
end
end
 
--- Affecte une valeur dans une clé d’une table, en utilisant un chemin en
--- notation pointée
local function set_key_path(t, key, default_key, value)
local left, right = split_delimiter(key, ".")
if not right and default_key then
right = default_key
end
if not right then
t[left] = value
else
if not t[left] then
t[left] = {}
end
set_key_path(t[left], right, nil, value)
end
end
 
--[======[ Représentation intermédiaire du flowchart ]======]--
 
local link_separator = "->"
local group_prefix = "group "
 
--- Lit la définition d’un flowchart
function p.read_flowchart(args)
local nodes = {}
local groups = {}
local links = {}
for key, value in pairs(args) do
if type(key) == "number" then
key = value
value = nil
end
local is_group = string.find(key, group_prefix, 1, true) == 1
local is_link = string.find(key, link_separator, 1, true)
if is_group then
-- Concerne un groupe de nœuds
local group_key = string.sub(key, #group_prefix + 1)
set_key_path(groups, group_key, "name", value)
elseif is_link then
-- Concerne un lien
local base, rest = split_delimiter(key, ".")
local from, to = split_delimiter(base, link_separator)
local link_key = nil
if not rest then
link_key = string.format("%s->%s", from, to)
else
link_key = string.format("%s->%s.%s", from, to, rest)
end
if not nodes[from] then
nodes[from] = {}
end
if not nodes[to] then
nodes[to] = {}
end
set_key_path(links, link_key, "name", value)
else
-- Concerne un nœud
set_key_path(nodes, key, "name", value)
end
end
return nodes, groups, links
end
 
--[======[ Génération de code Mermaid ]======]--
 
local orientations = {
["to bottom"] = "TB",
["to top"] = "BT",
["to right"] = "LR",
["to left"] = "RL",
}
 
local nodes_shapes = {
rectangle = '%s["%s"]',
rounded = '%s("%s")',
circle = '%s(("%s"))',
flag = '%s>"%s"]',
diamond = '%s{"%s"}',
}
 
local endings = {
plain = "---",
arrow = "-->",
}
 
local links_shapes = {
curve = "basis",
linear = "linear",
["step before"] = "stepBefore",
["step after"] = "stepAfter",
step = "step",
}
 
--- Génère le code Mermaid pour un flowchart
function p.flowchart_to_mermaid(frame, params, nodes, groups, links)
local lines = {}
local orientation = params.orientation or "to bottom"
if not orientations[orientation] then
error(string.format(
'Orientation "%s" inconnue pour le flowchart. Les orientations possibles sont %s.',
orientation, get_table_keys(orientations)
), 0)
end
table.insert(lines, string.format("graph %s", orientations[orientation]))
-- Liste des nœuds membres de chaque groupe, construite en même temps
-- qu’on itère sur les nœuds pour les insérer dans la sortie
local groups_members = {}
for key, _ in pairs(groups) do
groups_members[key] = {}
end
-- Génère les nœuds
for key, properties in pairs(nodes) do
local id = generate_id(key)
local name = properties.name or key
local shape = properties.shape or "rounded"
if properties.group then
table.insert(groups_members[properties.group], id)
end
if not nodes_shapes[shape] then
error(string.format(
'Forme "%s" inconnue pour le nœud "%s". Les formes possibles sont %s.',
shape, name, get_table_keys(nodes_shapes)
), 0)
end
-- Forme et étiquette du nœud
table.insert(lines, string.format(nodes_shapes[shape], id, escape_quotes(name)))
-- Style
if properties.style then
local rules = {}
for property, value in pairs(properties.style) do
table.insert(rules, string.format("%s:%s", property, value))
end
table.insert(lines, string.format("style %s %s", id, table.concat(rules, ",")))
end
end
-- Génère les groupes
for key, properties in pairs(groups) do
local name = properties.name or key
table.insert(lines, string.format('subgraph %s', name))
for _, node in pairs(groups_members[key]) do
table.insert(lines, node)
end
table.insert(lines, "end")
end
-- Génère les liens
local link_number = 0
-- Classe CSS pour les noeuds invisibles
table.insert(lines, "classDef SkipLevel width:0px;")
for key, properties in pairs(links) do
local from, to = split_delimiter(key, link_separator)
local from_id = generate_id(from)
local to_id = generate_id(to)
local ending = properties.ending or "arrow"
if not endings[ending] then
error(string.format(
'Terminaison "%s" inconnue pour le lien "%s -> %s". Les terminaisons possibles sont %s.',
shape, from, to, get_table_keys(endings)
), 0)
end
-- Définit les noeuds permettant de sauter de niveau.
-- Voir https://github.com/mermaid-js/mermaid/issues/637 pour la technique
-- qui consiste en rajouter des noeuds invisibles.
local level = nodes[to].level
if level ~= '-' and level ~= nil then
level = tonumber(level)
if level == nil or level < 1 then
error(string.format('Le niveau du noeud %s doit être un nombre entier > 0.', to), 0)
end
local prev_id = from_id
local class = "class " .. from_id .. '-0'
for i = 1, level - 1 do
-- Ajoute un noeud invisible
local next_id = from_id .. '-' .. i
class = class .. ',' .. next_id
table.insert(lines, next_id .. '( )')
-- Ajoute une connexion entre les noeuds invisibles
table.insert(lines, prev_id .. " --- " .. next_id)
prev_id = next_id
end
table.insert(lines, class .. " SkipLevel")
-- La dernière connexion sera créée normalement
from_id = prev_id
end
if properties.name then
table.insert(lines, string.format('%s -- "%s" %s %s', from_id, escape_quotes(properties.name), endings[ending], to_id))
else
table.insert(lines, string.format("%s %s %s", from_id, endings[ending], to_id))
end
local shape = properties.shape or "curve"
if not links_shapes[shape] then
error(string.format(
'Forme "%s" inconnue pour le lien "%s -> %s". Les formes possibles sont %s.',
shape, from, to, get_table_keys(links_shapes)
), 0)
end
if shape ~= "linear" then
table.insert(lines, string.format("linkStyle %d interpolate %s", link_number, links_shapes[shape]))
end
link_number = link_number + 1
end
return table.concat(lines, "\n")
end
 
local themes = {
default = true,
neutral = true,
forest = true,
dark = true,
}
 
--- Appelle l’extension Mermaid
function p.render_mermaid(frame, params, nodes, groups, links)
local mermaid = p.flowchart_to_mermaid(frame, params, nodes, groups, links)
local theme = params.theme or "neutral"
if not themes[theme] then
error(string.format(
'Thème "%s" inconnu pour le flowchart. Les thèmes possibles sont %s.',
theme, get_table_keys(themes)
), 0)
end
local rendered_mermaid = frame:callParserFunction(
"#mermaid", mermaid,
"config.theme = " .. theme
)
if params.debug then
dump_params = mw.text.nowiki(mw.dumpObject(params))
dump_nodes = mw.text.nowiki(mw.dumpObject(nodes))
dump_groups = mw.text.nowiki(mw.dumpObject(groups))
dump_links = mw.text.nowiki(mw.dumpObject(links))
dump_mermaid = mw.text.nowiki(mermaid)
return string.format([[
<h4>Représentation interne</h4>
<table>
<tr>
<th>params</th>
<th>nodes</th>
<th>groups</th>
<th>links</th>
</tr>
<tr>
<td><pre>%s</pre></td>
<td><pre>%s</pre></td>
<td><pre>%s</pre></td>
<td><pre>%s</pre></td>
</tr>
</table>
<h4>Code Mermaid</h4>
<pre>%s</pre>
<h4>Résultat</h4>
%s
]], dump_params, dump_nodes, dump_groups, dump_links, dump_mermaid, rendered_mermaid)
else
return rendered_mermaid
end
end
 
--[======[ Interface ]======]--
 
function p.render(frame)
-- Normalise les arguments
local args = getArgs(frame, {
wrappers = 'Modèle:Flowchart'
})
 
-- Lit et consomme les paramètres généraux du flowchart préfixés par "$"
local params = {}
for args_key, value in pairs(args) do
local key = args_key
if type(args_key) == "number" then
key = value
value = "true"
end
if string.sub(key, 1, 1) == "$" then
params[string.sub(key, 2)] = value
args[args_key] = nil
end
end
local nodes, groups, links = p.read_flowchart(args)
return p.render_mermaid(frame, params, nodes, groups, links)
end
end


return "Flowchart"
return p

Dernière version du 6 octobre 2020 à 08:34


Utilisation

Page principale: Aide:Diagramme

Permet d'afficher un digramme de type "Flowchart" (algorithme). L'utilisation de ce modèle est différente car il ne possède pas de nombre de paramètres définis et les paramètres sont nommés selon la fonction qu'ils occupent dans le flowchart. Seuls les paramètres débutant par $ sont fixes.

Il est conseillé de passer le wikicode pour faire l'édition de ce modèle. L'éditeur visuel n'étant pas adapté à ce cas d'utilisation.

Nœuds

Sous la forme id nœud=Étiquette à afficher pour le nœud, quasiment tous les caractères sont autorisés dans l’identifiant du nœud, sauf ceux utilisés pour déclarer un lien, un paramètre général ou un groupe. On peut en plus définir des propriétés pour les nœuds, telles que :

  • id nœud.shape=... spécifie la forme du nœud, parmi rounded (par défaut), rectangle, circle, flag, diamond.
  • id nœud.group=... définit le groupe de nœuds auquel appartient ce nœud, par défaut aucun.
  • id nœud.style.fill=... couleur de remplissage du nœud, par défaut c’est celle du thème Mermaid actif.
  • id nœud.style.stroke=... idem pour la bordure du nœud ( exemple: red,stroke-width:4px,stroke-dasharray: 5 5)

Liens

Ajout d’un lien entre deux nœuds. Sous la forme id nœud d’origine -> id nœud d’arrivée, ou id nœud d’origine -> id nœud d’arrivée=Étiquette du lien pour ajouter une étiquette. Comme pour les définitions de nœuds, on peut définir des propriétés pour le lien, telles que :

  • id nœud d’origine -> id nœud d’arrivée.shape=... spécifie la forme du lien, parmi curve (par défaut), linear, step, step before, step after.
  • id nœud d’origine -> id nœud d’arrivée.ending=... peut valoir arrow pour ajouter une flèche au bout du lien (par défaut), ou plain pour ne rien y mettre.

Groupes

Définition d’un groupe de nœuds. Les nœuds sont ajoutés à un groupe en affectant leur propriété .group=id du groupe. On peut en plus spécifier l’étiquette du groupe avec la syntaxe group id du groupe=Étiquette du groupe (préfixé de group).

Exemple

{{Flowchart
| $orientation = to right
| Start = Boîte de début
| Start -> A
| A = Lien vers une [[AAA|maladie]]
| A -> End
| End.group = groupe
| group groupe = Un groupe
| Start -> B
| B = Texte en '''gras'''<br>Avec une autre ligne.<br> Et une autre.
| B -> B2
| B2 = Une condition?
| B2.shape = diamond
| B2.style.fill = #ff6666
| B2 -> B3 = Oui
| B3.group = groupe
| B2 -> End = Non
| Start -> C
| C -> Fin 2
| Fin 2.level = 2
| Fin 2.shape = rectangle
| Fin 2.style.fill = #ff9900
}}

Paramètres

Génère un diagramme de type Flowchart (algorithme)

[Modifier les données du modèle]

Paramètres du modèle

La mise en forme multiligne est préférée pour ce modèle.

ParamètreDescriptionTypeÉtat
titre$titre

Titre du graphique

Contenufacultatif
Orientation$orientation

Orientation du flowchart, peut être to bottom, to right, to top, to left.

Par défaut
to bottom
Chaînefacultatif
Largeur$largeur

Force une largeur en pixels. Utile pour agrandir les flowcharts imposants.

Exemple
1200
Nombrefacultatif
Déboggage$debug

Active le mode déboggage

Par défaut
0
Booléenfacultatif

Notes techniques

  • En raison d'un conflit avec l'extension Flow, l'affichage des Flowcharts dans les discussions ne fonctionne pas car la librairie mermaid n'est pas chargée. Un patch a été ajouté dans MediaWiki:Common.js pour pallier à ce problème. Un bogue a été soumis auprès des développeurs.
  • De base, Lua ne parse pas de Wikicode à l'interne, une fonction de parsing a donc été rajoutée à LocalSettings.js

local p = {}

--[======[ Fonctions utilitaires ]======]--

local getArgs = require("Module:Arguments").getArgs

--- Récupère la liste des clés d’un tableau associatif
local function get_table_keys(t)
	local keys = {}
	
	for key, _ in pairs(t) do
		table.insert(keys, '"' .. key .. '"')
	end
	
	return table.concat(keys, ", ")
end

--- Convertit un identifiant d’objet en identifiant utilisé en syntaxe Mermaid
local function generate_id(id)
	-- On utilise une version hachée de l’identifiant de chaque objet (avec un
	-- algorithme de hachage faible, acceptable ici car nous n’en faisons pas
	-- une utilisation cryptographique) afin de permettre l’utilisation de
	-- caractères arbitraires dans le Wikicode sans poser de problèmes au
	-- parseur Mermaid
	return mw.hash.hashValue("md5", id)
end

--- Échappe les guillemets droits utilisés dans une étiquette
local function escape_quotes(label)
	return string.gsub(label, '"', "#quot;")
end

--- Découpe une chaîne autour de la première occurrence d’un délimiteur
--- et ignore les caractères blancs autour des deux segments résultant

-- Liste des caractères Unicode blancs, tirée de
-- <https://en.wikipedia.org/wiki/Unicode_character_property#Whitespace>
local whitespace = mw.ustring.char(
	0x9, 0xA, 0xB, 0xC, 0xD, 0x20, 0x85, 0xA0, 0x1680,
	0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006,
	0x2007, 0x2008, 0x2009, 0x200A, 0x2028, 0x2029, 0x202F,
	0x205F, 0x3000
)

local function split_delimiter(s, delim)
	local d_start, d_end = string.find(s, delim, 1, true)
	
	if d_start and d_end then
		local left = mw.text.trim(string.sub(s, 1, d_start - 1), whitespace)
		local right = mw.text.trim(string.sub(s, d_end + 1), whitespace)
		return left, right
	else
		return s
	end
end

--- Affecte une valeur dans une clé d’une table, en utilisant un chemin en
--- notation pointée
local function set_key_path(t, key, default_key, value)
	local left, right = split_delimiter(key, ".")
	
	if not right and default_key then
		right = default_key
	end
	
	if not right then
		t[left] = value
	else
		if not t[left] then
			t[left] = {}
		end
		
		set_key_path(t[left], right, nil, value)
	end
end

--[======[ Représentation intermédiaire du flowchart ]======]--

local link_separator = "->"
local group_prefix = "group "

--- Lit la définition d’un flowchart
function p.read_flowchart(args)
	local nodes = {}
	local groups = {}
	local links = {}
	
	for key, value in pairs(args) do
		if type(key) == "number" then
			key = value
			value = nil
		end
		
		local is_group = string.find(key, group_prefix, 1, true) == 1
		local is_link = string.find(key, link_separator, 1, true)
		
		if is_group then
			-- Concerne un groupe de nœuds
			local group_key = string.sub(key, #group_prefix + 1)
			
			set_key_path(groups, group_key, "name", value)
		elseif is_link then
			-- Concerne un lien
			local base, rest = split_delimiter(key, ".")
			local from, to = split_delimiter(base, link_separator)
			local link_key = nil
			
			if not rest then
				link_key = string.format("%s->%s", from, to)
			else
				link_key = string.format("%s->%s.%s", from, to, rest)
			end
			
			if not nodes[from] then
				nodes[from] = {}
			end
			
			if not nodes[to] then
				nodes[to] = {}
			end
			
			set_key_path(links, link_key, "name", value)
		else
			-- Concerne un nœud
			set_key_path(nodes, key, "name", value)
		end
	end
	
	return nodes, groups, links
end

--[======[ Génération de code Mermaid ]======]--

local orientations = {
	["to bottom"] = "TB",
	["to top"] = "BT",
	["to right"] = "LR",
	["to left"] = "RL",
}

local nodes_shapes = {
	rectangle = '%s["%s"]',
	rounded = '%s("%s")',
	circle = '%s(("%s"))',
	flag = '%s>"%s"]',
	diamond = '%s{"%s"}',
}

local endings = {
	plain = "---",
	arrow = "-->",
}

local links_shapes = {
	curve = "basis",
	linear = "linear",
	["step before"] = "stepBefore",
	["step after"] = "stepAfter",
	step = "step",
}

--- Génère le code Mermaid pour un flowchart
function p.flowchart_to_mermaid(frame, params, nodes, groups, links)
	local lines = {}
	local orientation = params.orientation or "to bottom"
	
	if not orientations[orientation] then
		error(string.format(
			'Orientation "%s" inconnue pour le flowchart. Les orientations possibles sont %s.',
			orientation, get_table_keys(orientations)
		), 0)
	end
	
	table.insert(lines, string.format("graph %s", orientations[orientation]))
	
	-- Liste des nœuds membres de chaque groupe, construite en même temps
	-- qu’on itère sur les nœuds pour les insérer dans la sortie
	local groups_members = {}
	
	for key, _ in pairs(groups) do
		groups_members[key] = {}
	end
	
	-- Génère les nœuds
	for key, properties in pairs(nodes) do
		local id = generate_id(key)
		local name = properties.name or key
		local shape = properties.shape or "rounded"
		
		if properties.group then
			table.insert(groups_members[properties.group], id)
		end
		
		if not nodes_shapes[shape] then
			error(string.format(
				'Forme "%s" inconnue pour le nœud "%s". Les formes possibles sont %s.',
				shape, name, get_table_keys(nodes_shapes)
			), 0)
		end
		
		-- Forme et étiquette du nœud
		table.insert(lines, string.format(nodes_shapes[shape], id, escape_quotes(name)))
		
		-- Style
		if properties.style then
			local rules = {}
			
			for property, value in pairs(properties.style) do
				table.insert(rules, string.format("%s:%s", property, value))
			end
			
			table.insert(lines, string.format("style %s %s", id, table.concat(rules, ",")))
		end
	end
	
	-- Génère les groupes
	for key, properties in pairs(groups) do
		local name = properties.name or key
		
		table.insert(lines, string.format('subgraph %s', name))
		
		for _, node in pairs(groups_members[key]) do
			table.insert(lines, node)
		end
		
		table.insert(lines, "end")
	end
	
	-- Génère les liens
	local link_number = 0
	
	-- Classe CSS pour les noeuds invisibles
	table.insert(lines, "classDef SkipLevel width:0px;")
	
	for key, properties in pairs(links) do
		local from, to = split_delimiter(key, link_separator)
		local from_id = generate_id(from)
		local to_id = generate_id(to)
		
		local ending = properties.ending or "arrow"
		
		if not endings[ending] then
			error(string.format(
				'Terminaison "%s" inconnue pour le lien "%s -> %s". Les terminaisons possibles sont %s.',
				shape, from, to, get_table_keys(endings)
			), 0)
		end
		
		-- Définit les noeuds permettant de sauter de niveau.
		-- Voir https://github.com/mermaid-js/mermaid/issues/637 pour la technique
		-- qui consiste en rajouter des noeuds invisibles.
		local level = nodes[to].level
		
		if level ~= '-' and level ~= nil then
			level = tonumber(level)
			
			if level == nil or level < 1 then
				error(string.format('Le niveau du noeud %s doit être un nombre entier > 0.', to), 0)
			end
			
			local prev_id = from_id
			local class = "class " .. from_id .. '-0'
			
			for i = 1, level - 1 do
				-- Ajoute un noeud invisible
				local next_id = from_id .. '-' .. i
				class = class .. ',' .. next_id
				table.insert(lines, next_id .. '( )')
				
				-- Ajoute une connexion entre les noeuds invisibles
				table.insert(lines, prev_id .. " --- " .. next_id)
				prev_id = next_id
			end
			
			table.insert(lines, class .. " SkipLevel")
			
			-- La dernière connexion sera créée normalement
			from_id = prev_id
		end
		
		if properties.name then
			table.insert(lines, string.format('%s -- "%s" %s %s', from_id, escape_quotes(properties.name), endings[ending], to_id))
		else
			table.insert(lines, string.format("%s %s %s", from_id, endings[ending], to_id))
		end
		
		local shape = properties.shape or "curve"
		
		if not links_shapes[shape] then
			error(string.format(
				'Forme "%s" inconnue pour le lien "%s -> %s". Les formes possibles sont %s.',
				shape, from, to, get_table_keys(links_shapes)
			), 0)
		end
		
		if shape ~= "linear" then
			table.insert(lines, string.format("linkStyle %d interpolate %s", link_number, links_shapes[shape]))
		end
		
		link_number = link_number + 1
	end
	
	return table.concat(lines, "\n")
end

local themes = {
	default = true,
	neutral = true,
	forest = true,
	dark = true,
}

--- Appelle l’extension Mermaid
function p.render_mermaid(frame, params, nodes, groups, links)
	local mermaid = p.flowchart_to_mermaid(frame, params, nodes, groups, links)
	local theme = params.theme or "neutral"
	
	if not themes[theme] then
		error(string.format(
			'Thème "%s" inconnu pour le flowchart. Les thèmes possibles sont %s.',
			theme, get_table_keys(themes)
		), 0)
	end
	
	local rendered_mermaid = frame:callParserFunction(
		"#mermaid", mermaid,
		"config.theme = " .. theme
	)
	
	if params.debug then
		dump_params = mw.text.nowiki(mw.dumpObject(params))
		dump_nodes = mw.text.nowiki(mw.dumpObject(nodes))
		dump_groups = mw.text.nowiki(mw.dumpObject(groups))
		dump_links = mw.text.nowiki(mw.dumpObject(links))
		dump_mermaid = mw.text.nowiki(mermaid)
		
		return string.format([[
			<h4>Représentation interne</h4>
			
			<table>
				<tr>
					<th>params</th>
					<th>nodes</th>
					<th>groups</th>
					<th>links</th>
				</tr>
				<tr>
					<td><pre>%s</pre></td>
					<td><pre>%s</pre></td>
					<td><pre>%s</pre></td>
					<td><pre>%s</pre></td>
				</tr>
			</table>
			
			<h4>Code Mermaid</h4>
			
			<pre>%s</pre>
			
			<h4>Résultat</h4>
			
			%s
		]], dump_params, dump_nodes, dump_groups, dump_links, dump_mermaid, rendered_mermaid)
	else
		return rendered_mermaid
	end
end

--[======[ Interface ]======]--

function p.render(frame)
	-- Normalise les arguments
	local args = getArgs(frame, {
		wrappers = 'Modèle:Flowchart'
	})

	-- Lit et consomme les paramètres généraux du flowchart préfixés par "$"
	local params = {}
	
	for args_key, value in pairs(args) do
		local key = args_key
		
		if type(args_key) == "number" then
			key = value
			value = "true"
		end
		
		if string.sub(key, 1, 1) == "$" then
			params[string.sub(key, 2)] = value
			args[args_key] = nil
		end
	end
	
	local nodes, groups, links = p.read_flowchart(args)
	return p.render_mermaid(frame, params, nodes, groups, links)
end

return p