Source code for feynml.sheet
import logging
import warnings
from typing import List
import cssutils
from cssselect import GenericTranslator, SelectorError
from lxml import etree
from feynml.id import Identifiable
from feynml.styled import Styled
from feynml.xml import XML
cssutils.log.setLevel(logging.CRITICAL)
default_sheet = cssutils.parseString(
"""
/*************************************************************************/
/* Diagram */
/*************************************************************************/
diagram {
direction : right;
layout : neato;
}
/*************************************************************************/
/* Vertex */
/*************************************************************************/
[shape=dot] {
symbol : dot;
}
[shape=empty] {
symbol : empty;
}
[shape=blob] {
symbol : blob;
}
[shape=star] {
symbol : star;
}
[shape=square] {
symbol : square;
}
[shape=triangle] {
symbol : triangle;
}
[shape=diamond] {
symbol : diamond;
}
[shape=pentagon] {
symbol : pentagon;
}
[shape=hexagon] {
symbol : hexagon;
}
[shape=triagram] {
symbol : triagram;
}
[shape=tetragram] {
symbol : tetragram;
}
[shape=pentagram] {
symbol : pentagram;
}
[shape=cross] {
symbol : cross;
}
[shape=triacross] {
symbol : triacross;
}
[shape=pentacross] {
symbol : pentacross;
}
[shape=hexacross] {
symbol : pentacross;
}
/*************************************************************************/
/* Propagator */
/*************************************************************************/
/* General */
[type=meson] {
line: meson;
arrow-sense: 0;
double-distance: 3;
}
[type=baryon] {
line: baryon;
arrow-sense: 1;
double-distance: 3;
}
[type="anti baryon"] {
line: anti baryon;
arrow-sense: -1;
double-distance: 3;
}
[type=fermion] {
line: fermion;
arrow-sense: 1;
}
[type="anti fermion"] {
line: anti fermion;
arrow-sense: -1;
}
[type=boson] {
line: boson;
arrow-sense: 0;
}
[type=vector] {
line: vector;
arrow-sense: 0;
}
[type=scalar] {
line: scalar;
arrow-sense: 0;
}
[type=majorana] {
line: majorana;
}
[type=anti majorana] {
line: anti majorana;
}
/* SM */
[type=photon] {
line: photon;
arrow-sense: 0;
}
[type=higgs] {
line: higgs;
arrow-sense: 0;
}
[type=gluon] {
line: gluon;
arrow-sense: 0;
xamp : 0.025;
yamp : 0.035;
nloops : 7;
}
[type=ghost] {
line: ghost;
arrow-sense: 1;
}
[type=anti ghost] {
line: ghost;
arrow-sense: -1;
}
/* BSM */
[type=graviton] {
line: graviton;
arrow-sense: 0;
}
[type=gluino] {
line: gluino;
arrow-sense: 0;
xamp : 0.025;
yamp : 0.035;
nloops : 7;
}
[type=squark] {
line: squark;
arrow-sense: 1;
}
[type=slepton] {
line: slepton;
arrow-sense: 1;
}
[type=anti squark] {
line: anti squark;
arrow-sense: -1;
}
[type=anti slepton] {
line: anti slepton;
arrow-sense: -1;
}
[type=gaugino] {
line: gaugino;
arrow-sense: 0;
}
[type=neutralino] {
line: neutralino;
arrow-sense: 0;
}
[type=chargino] {
line: chargino;
arrow-sense: 0;
}
[type=higgsino] {
line: higgsino;
arrow-sense: 0;
}
[type=gravitino] {
line: gravitino;
arrow-sense: 0;
}
/* util */
[type=phantom] {
line: phantom;
arrow-sense: 0;
}
[type=line] {
line: line;
arrow-sense: 0;
}
"""
)
[docs]def get_default_sheet() -> cssutils.css.CSSStyleSheet:
"""Return the default sheet."""
return default_sheet
[docs]class SheetHandler:
"""Sheet class."""
default_sheet: cssutils.css.CSSStyleSheet = get_default_sheet()
[docs] def get_sheets(self) -> List[cssutils.css.CSSStyleSheet]:
"""Return the sheet."""
return [self.default_sheet]
[docs] def get_sheet(self) -> cssutils.css.CSSStyleSheet:
"""Return the sheet."""
return self.default_sheet
[docs] def with_sheet(self, sheet):
"""Return the object with the sheet."""
self.default_sheet = sheet
return self
[docs] def get_style(self, obj, xml: XML = None) -> cssutils.css.CSSStyleDeclaration:
"""
Get the style of an object.
This is prefered over accessing the style attribute directly, since it includes class and pdgid definitions.
"""
# selectorText is string
css = []
# global style
if isinstance(obj, Identifiable):
css += [self._get_obj_style(obj, xml=xml)]
if isinstance(obj, Styled):
# specific attribute style
css += [obj.style]
return cssutils.css.CSSStyleDeclaration(
cssText=";".join([c.cssText for c in css])
)
[docs] def get_style_property(self, obj, property_name, xml: XML = None) -> str:
"""
Get a style property of an object.
"""
style = self.get_style(obj, xml=xml)
p = style.getProperty(property_name)
if p is None:
return None
else:
return p.value
def _get_obj_style(
self, obj: Identifiable, xml: XML = None
) -> cssutils.css.CSSStyleDeclaration:
if xml is not None:
document = etree.XML(xml.to_xml().encode("ascii"))
else:
warnings.warn("No XML provided, using empty XML")
document = etree.XML("<feynml></feynml>")
def lambdaselector(s, obj=obj, document=document):
try:
expression = GenericTranslator().css_to_xpath(s)
except SelectorError:
warnings.warn("Invalid selector: " + s)
return False
return obj.id in [e.get("id") for e in document.xpath(expression)]
return self._get_style(lambdaselector)
def _get_style(self, lambdaselector) -> cssutils.css.CSSStyleDeclaration:
ret = []
sheets = self.get_sheets()
for sheet in sheets:
idd = []
cls = []
rest = []
glob = []
for rule in sheet:
if rule.type == rule.STYLE_RULE:
s = rule.selectorText
if lambdaselector(s):
if s.startswith("#"):
idd.append(rule)
elif s.startswith("["):
rest.append(rule)
elif s.startswith(":"):
rest.append(rule)
elif s.startswith("*"):
glob.append(rule)
elif "." in s:
cls.append(rule)
else:
rest.append(rule)
ret += reversed(idd + cls + rest + glob)
# sort rules by priority
return cssutils.css.CSSStyleDeclaration(
cssText=";".join([r.style.cssText for r in ret])
)
[docs] def add_rule(self, rule: str):
"""
Add a rule to the style.
"""
self.get_sheet().add(rule)
return self
[docs] def add_rules(self, rules: str):
"""
Add rules to the style.
"""
self.with_sheet(
cssutils.parseString(
self.get_sheet().cssText.decode("utf-8") + "\n" + rules
)
)
return self
[docs] def with_rule(self, rule: str):
"""
Replace rules of the style.
"""
return self.with_rules(rule)
[docs] def with_rules(self, rules: str):
"""
Replace rules of the style.
"""
self.with_sheet(cssutils.parseString(rules))
return self