Edge Rewrite
// HTMLRewriter · presentation

This page was redesigned at the edge.

Cloudflare fetched the original article and streamed it through HTMLRewriter to apply an entirely new visual system without rebuilding the source page.

Jump to content

Module:SMILES2IUPAC

From Wikipedia, the free encyclopedia

local Parser = require('Module:SMILES2IUPAC/Parser')
local Alkanes = require('Module:SMILES2IUPAC/Alkanes')
local Alkenes = require('Module:SMILES2IUPAC/Alkenes')
local Dienes = require('Module:SMILES2IUPAC/Dienes')
local Alkynes = require('Module:SMILES2IUPAC/Alkynes')
local Enynes = require('Module:SMILES2IUPAC/Enynes')
local Functional = require('Module:SMILES2IUPAC/Functional')

local p = {}

local namingSubmodules = {
	{ name = 'Functional', tryName = Functional.name },
	{ name = 'Enynes', tryName = Enynes.name },
	{ name = 'Dienes', tryName = Dienes.name },
	{ name = 'Alkenes', tryName = Alkenes.name },
	{ name = 'Alkynes', tryName = Alkynes.name },
	{ name = 'Alkanes', tryName = Alkanes.name },
}


--- Converts a SMILES string into an IUPAC name.
-- @param smiles string
-- @return name string on success, or nil, errorMessage on failure.
function p.nameFromSmiles(smiles)
	local graph, parseErr = Parser.parse(smiles)
	if not graph then
		return nil, 'could not parse SMILES: ' .. parseErr
	end

	local lastErr
	for _, submodule in ipairs(namingSubmodules) do
		local name, err = submodule.tryName(graph)
		if name then
			return name
		end
		lastErr = submodule.name .. ': ' .. tostring(err)
	end

	return nil, 'no naming rule could handle this molecule yet (' .. tostring(lastErr) .. ')'
end

--- {{#invoke:SMILES2IUPAC|main|<smiles>}} entry point.
function p.main(frame)
	local args = frame.args
	if args.smiles == nil and args[1] == nil and frame:getParent() then
		args = frame:getParent().args
	end
	local smiles = args.smiles or args[1]
	if not smiles or smiles == '' then
		return 'Error: no SMILES string given'
	end

	local ok, nameOrErr, err = pcall(p.nameFromSmiles, smiles)
	if not ok then
		return 'Error: internal error while naming SMILES (' .. tostring(nameOrErr) .. ')'
	end
	if not nameOrErr then
		return 'Error: ' .. tostring(err)
	end
	return nameOrErr
end
function p.testParser(frame)
    local smiles = frame.args[1] or frame.args.smiles
    local graph, err = Parser.parse(smiles)

    if not graph then
        return 'ERROR: ' .. err
    end

    local out = {}

    table.insert(out, 'Atoms:')
    for i, atom in ipairs(graph.atoms) do
        table.insert(out, i .. ': ' .. atom.element)
    end

    table.insert(out, 'Bonds:')
    for _, bond in ipairs(graph.bonds) do
        table.insert(
            out,
            bond.a .. ' -- ' .. bond.b .. ' (order=' .. bond.order .. ')'
        )
    end

    return table.concat(out, '\n')
end

function p.debugName(frame)

	local smiles =
		frame.args[1]
		or frame.args.smiles

	if not smiles or smiles == '' then
		return 'Error: no SMILES supplied'
	end

	local graph, parseErr =
		Parser.parse(smiles)

	if not graph then
		return 'Parser: ' .. tostring(parseErr)
	end

	local out = {}

	for _, submodule in ipairs(namingSubmodules) do

		local ok, name, err =
			pcall(
				submodule.tryName,
				graph
			)

		if not ok then

			table.insert(
				out,
				submodule.name
				.. ': CRASH: '
				.. tostring(name)
			)

		elseif name then

			table.insert(
				out,
				submodule.name
				.. ': PASS -> '
				.. tostring(name)
			)

		else

			table.insert(
				out,
				submodule.name
				.. ': FAIL -> '
				.. tostring(err)
			)
		end
	end

	return table.concat(out, '\n')
end
function p.debugGraph(frame)

	local smiles =
		frame.args[1]
		or frame.args.smiles

	if not smiles or smiles == '' then
		return 'Error: no SMILES supplied'
	end

	local graph, err =
		Parser.parse(smiles)

	if not graph then
		return 'Parser ERROR: ' .. tostring(err)
	end

	local out = {}

	table.insert(
		out,
		'SMILES: ' .. smiles
	)

	table.insert(
		out,
		'Atoms:'
	)

	for i, atom in ipairs(graph.atoms) do
		table.insert(
			out,
			string.format(
				'%d: %s',
				i,
				atom.element
			)
		)
	end

	table.insert(
		out,
		'Bonds:'
	)

	for i, bond in ipairs(graph.bonds) do
		table.insert(
			out,
			string.format(
				'%d: %d -- %d (order=%d)',
				i,
				bond.a,
				bond.b,
				bond.order
			)
		)
	end

	return table.concat(
		out,
		'\n'
	)
end
function p.debugAlkene(frame)

	local smiles =
		frame.args[1]
		or frame.args.smiles

	if not smiles or smiles == '' then
		return 'Error: no SMILES'
	end

	local graph, err =
		Parser.parse(smiles)

	if not graph then
		return 'Parser: ' .. tostring(err)
	end

	local ok, result =
		pcall(
			Alkenes.debugChains,
			graph
		)

	if not ok then
		return 'Alkenes ERROR: ' .. tostring(result)
	end

	return result
end
return p