CSS4J User Guide
This project is an implementation of W3C's CSS Object Model API in the Java™ language, and also adds CSS support to the DOM4J package. It targets several different use cases, with functionalities from style sheet error detection to style computation.
Java 8 and later versions are supported (the library is fully modular).
Overview
This library provides a number of classes to deal with different CSS Object Model abstractions. For example:
- AbstractCSSStyleSheet for style sheets.
- StyleRule for style rules.
- StyleValue
for values like
rgb(12% 0% 67%)
orvar(--customProperty)
. - LexicalUnit for low-level CSS syntax.
- Selector and SelectorList for CSS Selectors.
You can use those classes as stand-alone objects or have them all together in a document, one of the implementations of the DOM-based CSSDocument interface:
- HTMLDocument and DOMDocument of css4j's native DOM, available from the core css4j module. Native DOM is recommended for new projects.
- The StylableDocumentWrapper can wrap any valid DOM document, thus adding (read-only) style capabilities to a pre-existing document in your favourite DOM implementation. The documentation often refers to this approach as the "DOM Wrapper", and is also available from the core css4j module.
- XHTMLDocument is a DOM4J subclass which comes with the css4j-dom4j module. Recommended only for dealing with legacy DOM4J code.
An important advantage of using DOM-based interfaces is that you can use the same or very similar methods in your web browser's Javascript (with the exception of the CSSValue API which is based on an old W3C standard instead of the more recent Houdini's Typed OM).
Choosing a DOM implementation
Once you have chosen which DOM you prefer to use, the first step is to obtain an instance of a compatible CSSStyleSheetFactory.
There are three implementations of that interface:
- CSSDOMImplementation, the native DOM implementation.
- DOMCSSStyleSheetFactory for the DOM Wrapper.
- If you use DOM4J, get it through XHTMLDocumentFactory.getInstance().getStyleSheetFactory().
Even if you want to use only stand-alone style sheets, you should use one of the above factories to create them with the createStyleSheet("title", "media") method.
The style sheet objects created by that method are empty, but you can load the style sheet rules with the AbstractCSSStyleSheet.parseStyleSheet(reader, short) method (see Parsing a Style Sheet).
Modules
The project is organized in several modules:
css4j
core module (providing the io.sf.carte.css4j JPMS module), which depends on the next two (they are included in the Zip distribution):carte-util
, a very small collection of interfaces and utility classes.tokenproducer
, the low-level parser at the core of css4j.css4j-agent
, an optional collection of agent-related classes that makes the processing of remote documents a bit easier. JPMS module: io.sf.carte.css4j.agent.net.css4j-awt
, a small set of AWT-related utility classes (also optional). Module: io.sf.carte.css4j.awt.css4j-dom4j
: to use css4j together with dom4j, if you prefer that API. The JPMS module name is io.sf.carte.css4j.dom4j.xml-dtd
is a small set of classes to aid in the processing of XML DTDs, including the useful DefaultEntityResolver. It is not needed if you do not process XML. The JPMS module is io.sf.carte.xml.dtd.
In general, you'll need to have at least css4j
, carte-util
and tokenproducer
in your classpath/modulepath.
If you use Gradle or Apache Maven, you may want to look at each module's
build.gradle
files (or even better, the .pom
or the .module
files at the repository) to check for the specific module dependencies.
Recent css4j-*
artifacts are compatible with css4j
releases that have the same major version number, for example css4j-dom4j
3.6.1 is compatible with
css4j
3.6.1 and also with 3.9.1. (css4j-dom4j 4.x is recommended for css4j 4.x compatibility)
Usage from a Gradle project
If your Gradle project depends on css4j, you can use this project's own Maven repository in a repositories
section of
your build file:
repositories {
maven {
url "https://css4j.github.io/maven/"
mavenContent {
releasesOnly()
}
content {
includeGroup 'io.sf.carte'
includeGroup 'io.sf.jclf'
includeGroup 'xmlpull'
includeGroup 'xpp3'
}
}
}
please use this repository only for the artifact groups listed in the includeGroup
statements.
Then, in your build.gradle
file:
dependencies {
api "io.sf.carte:css4j:${css4jVersion}"
}
where css4jVersion
could be defined in a gradle.properties
file.
Usage from a Maven build
If you build your project (that depends on css4j) with Apache Maven, please note that some of the css4j dependencies are not in Maven Central:
- JCLF.
- XMLPull-XPP3 (v1.2, dependency of the DOM4J module only).
You may want to install them manually into your local Maven repository, which can be done easily with the:
scripts.
You can also directly install the CSS4J artifacts into your local Maven repository, with the similar
install-css4j.sh
.
And then, add the following to the <dependencies>
section of your pom.xml
:
<!-- This artifact is not in Maven Central -->
<dependency>
<groupId>io.sf.carte</groupId>
<artifactId>css4j</artifactId>
<version>${css4j.version}</version>
</dependency>
Using css4j's native DOM implementation
You can create a DOM document from scratch and use the related DOM methods to programmatically build a document: just use the provided DOM implementation
(io.sf.carte.doc.dom.CSSDOMImplementation
). But if you want to parse an existing document, the procedure depends on the type of document: to parse
an XML document (including XHTML documents), you can use this library's XMLDocumentBuilder
with the SAX parser provided by the JDK, while to parse
an HTML one (or an XHTML document that does not use namespace prefixes) you can use the validator.nu
HTML5 parser (be sure to use the latest version from the nu.validator
Maven group id).
An example with that parser follows:
import java.io.Reader;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import io.sf.carte.doc.dom.CSSDOMImplementation;
import io.sf.carte.doc.dom.DOMElement;
import io.sf.carte.doc.dom.HTMLDocument;
import io.sf.carte.doc.dom.XMLDocumentBuilder;
import io.sf.carte.doc.style.css.CSSComputedProperties;
import io.sf.carte.doc.style.css.CSSTypedValue;
import io.sf.carte.doc.style.css.RGBAColor;
import io.sf.carte.doc.xml.dtd.DefaultEntityResolver;
import nu.validator.htmlparser.common.XmlViolationPolicy;
import nu.validator.htmlparser.sax.HtmlParser;
[...]
// Instantiate DOM implementation (with default settings: no IE hacks accepted)
// and configure it
CSSDOMImplementation impl = new CSSDOMImplementation();
// Alternatively, impl = new CSSDOMImplementation(flags);
// Now load default HTML user agent sheets
impl.setDefaultHTMLUserAgentSheet();
// Prepare parser
HtmlParser parser = new HtmlParser(XmlViolationPolicy.ALTER_INFOSET);
parser.setCommentPolicy(XmlViolationPolicy.ALLOW);
parser.setXmlnsPolicy(XmlViolationPolicy.ALLOW);
// Prepare builder
XMLDocumentBuilder builder = new XMLDocumentBuilder(impl);
builder.setHTMLProcessing(true);
builder.setXMLReader(parser);
// Read the document to parse, and prepare source object
Reader re = ... [reader for HTML document]
InputSource source = new InputSource(re);
// Parse. If the document is not HTML, you want to use DOMDocument instead
HTMLDocument document = (HTMLDocument) builder.parse(source);
re.close();
// Set document URI
document.setDocumentURI("http://www.example.com/mydocument.html");
Now, you have a CSS-enabled document.
You can see the above code example (and others in this guide) in the Css4jTest.java example file.
Computing styles
To compute styles, use getComputedStyle:
DOMElement element = document.getElementById("someId");
CSSComputedProperties style = element.getComputedStyle(null);
// Next line could be 'String display = style.getDisplay();'
String display = style.getPropertyValue("display");
// If you use a factory that has been set to setLenientSystemValues(false), next
// line may throw an exception if the 'color' property was not specified.
// The default value for lenientSystemValues is TRUE.
RGBAColor color = ((CSSTypedValue) style.getPropertyCSSValue("color")).toRGBColor();
// Suppose that the linked style sheet located at 'css/sheet.css' declares:
// background-image: url('foo.png');
String image_css = style.getPropertyValue("background-image");
String image_uri = ((CSSTypedValue) style.getPropertyCSSValue("background-image")).getStringValue();
// Then, because we already set the document URI to "http://www.example.com/mydocument.html",
// image_css will be set to "url('http://www.example.com/css/foo.png')",
// and image_uri to "http://www.example.com/css/foo.png"
The CSSComputedProperties
interface extends W3C's CSSStyleDeclaration
for computed styles, adding methods like getComputedFontSize()
or getComputedLineHeight()
.
If you are computing styles for a specific medium, tell the document about it (see "Media Handling"):
document.setTargetMedium("print");
Conformance with the DOM specification
This library's native DOM implementation has some minor behavior differences with what is written in the DOM
Level 3 Core Specification. For example, on elements and attributes the Node.getLocalName()
method returns the tag name instead of
null
when the node was created with a DOM Level 1 method such as Document.createElement()
. Read the
io.sf.carte.doc.dom package
description for additional information.
Examples with DOM4J
To use the library with dom4j (using dom4j-like documents, elements and factory) you need the css4j-dom4j module in addition to the core module. The -dom4j module optionally depends on the -agent module, but you do not need the latter unless you plan to use the DOM4J agent.
For example, with Gradle:
dependencies {
api "io.sf.carte:css4j-dom4j:${css4jDom4jVersion}"
}
or with Apache Maven:
<dependency>
<groupId>io.sf.carte</groupId>
<artifactId>css4j-dom4j</artifactId>
<version>${css4jDom4j.version}</version>
</dependency>
The css4j-dom4j
artifact transitively implies the css4j
core module, but since both artifacts have
different release cycles you may want to add an explicit dependency for the core module, with the latest version.
As explained in the modules section, recent css4j-dom4j
artifacts are compatible with css4j
artifacts that have the same major version number, for example both css4j-dom4j
3.5.2 and 3.6.0 are compatible with
css4j
3.7.0.
Loading and parsing an XML document
This is the easiest way to parse an XML document to use this package with DOM4J, using that library's SAXReader
:
SAXReader reader = new SAXReader(XHTMLDocumentFactory.getInstance());
reader.setEntityResolver(new DefaultEntityResolver());
Reader re = ... [reader for HTML document]
XHTMLDocument document = (XHTMLDocument) reader.read(re);
As you see, a document factory called XHTMLDocumentFactory is used.
Once you got the element you want the computed style for (see, for example, the
DOM4J Quick Start Guide), just get it with a procedure analogous to the
ViewCSS
interface:
CSSComputedProperties style = ((CSSStylableElement) element).getComputedStyle(null);
String display = style.getPropertyValue("display");
Be careful to have the XHTMLDocumentFactory
loaded with the desired defaults, like the user agent style sheet
which was loaded by default in 1.0 but not in 2.0 and later.
It is also possible to parse an HTML5 document into a css4j-dom4j tree with the aforementioned validator.nu HTML5 parser:
XHTMLDocumentFactory factory = XHTMLDocumentFactory.getInstance();
// Next line is optional: default is TRUE, and is probably what you want
// factory.getStyleSheetFactory().setLenientSystemValues(false);
HtmlParser parser = new HtmlParser(XmlViolationPolicy.ALTER_INFOSET);
parser.setCommentPolicy(XmlViolationPolicy.ALLOW);
parser.setXmlnsPolicy(XmlViolationPolicy.ALLOW);
// Configure the SAXReader with the HtmlParser
SAXReader builder = new SAXReader(factory);
builder.setXMLReader(parser);
// Provide an error handler to avoid exceptions
ErrorHandler errorHandler = [...]
builder.setErrorHandler(errorHandler);
// We do not set the EntityResolver, the HtmlParser does not need it
Reader re = ... [reader for HTML document]
XHTMLDocument document = (XHTMLDocument) builder.read(re);
Or parse the document with the css4j's builder,
XMLDocumentBuilder
(which can account for things like implied HTML parent elements),
instead of dom4j's SAXReader
:
XHTMLDocumentFactory factory = XHTMLDocumentFactory.getInstance();
// Next line is optional: default is TRUE, and is probably what you want
// factory.getStyleSheetFactory().setLenientSystemValues(false);
HtmlParser parser = new HtmlParser(XmlViolationPolicy.ALTER_INFOSET);
parser.setCommentPolicy(XmlViolationPolicy.ALLOW);
parser.setXmlnsPolicy(XmlViolationPolicy.ALLOW);
XMLDocumentBuilder builder = new XMLDocumentBuilder(factory);
builder.setHTMLProcessing(true);
builder.setXMLReader(parser);
Reader re = ... [reader for XML document]
InputSource source = new InputSource(re);
XHTMLDocument document = (XHTMLDocument) builder.parse(source);
re.close();
Caveats about DOM4J and HTML
A plain HTML document may contain STYLE
elements with selectors like div>p
,
and css4j's native DOM handles that correctly. However, XML-oriented DOM implementations are likely to serialize
them as "div>p
", breaking the CSS. For example, if you serialize a DOM4J document
with asXML()
or code like the following:
Writer wri = ... [put your writer here]
OutputFormat format = OutputFormat.createPrettyPrint();
format.setXHTML(true);
HTMLWriter writer = new HTMLWriter(wri, format);
writer.write(document);
The result will be the "div>p
". As explained below, with other DOM implementations
it is possible to work around this problem if one serializes to XHTML with a properly
configured Transformer
, but not with DOM4J.
Usage with the DOM wrapper
If you choose to build your document with your favorite DOM implementation instead of the CSS4J one or the DOM4J back-end, you can use the DOMCSSStyleSheetFactory.createCSSDocument(document) method to wrap a pre-existing DOM Document. Example:
DOMCSSStyleSheetFactory cssFactory = new DOMCSSStyleSheetFactory();
CSSDocument document = cssFactory.createCSSDocument(otherDOMdocument);
Unlike the native DOM or the DOM4J back-end, the DOM resulting from the DOM wrapper is read-only, although you can change the values of some nodes.
Serializing HTML with an XML DOM
As was previously mentioned, if you serialize a plain HTML document
(which does not contain CDATA
sections) with an XML-oriented DOM, you can avoid serializing
div>p
as "div>p
" if you use a Transformer
which is
configured for the task. The code would be like the following:
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
// Put other Transformer configurations here
// ...
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
// Put the embedded style sheets inside CDATA
sections
transformer.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS, "script style");
Writer wri = ... [put your writer here]
transformer.transform(new DOMSource(document), new StreamResult(wri));
which —as the comment says— puts the embedded style sheets inside CDATA
sections.
Note, however, that:
- In HTML, the CDATA sections can only be used in foreign content —otherwise being considered as "bogus comments"— so you are now in XHTML instead of HTML.
- If you use the above code with css4j-dom4j (3.6.1 or later is required), it will not produce the desired result.
To handle HTML, the native DOM is recommended over any XML DOM.
Consistency of different DOM implementations
Beware that the computed styles found by each method (native DOM, DOM4J back-end or DOM wrapper) may not be completely identical, due to differences in the underlying document DOM implementations:
- XML-oriented DOM implementations do not implement the case sensitivity subtleties of HTML (although this library attempts to emulate the basics).
- The
:dir()
pseudo-class is not fully supported on DOM4J, due to limitations in its DOM support.
If you find a difference in styles computed from different back-ends that you believe to be a bug, please report it.
Accessing the declared style sheets
CSSOM indexed access
To access the styles declared in style sheets, we can use the relevant CSS Object Model methods. For example, suppose that the first style sheet of the document contains only the following rule:
div > .myClass {
font-size: 14pt;
color: var(--myColor, #46f);
}
then, to access that style sheet and that rule we could use something like this:
/*
* Access style sheet(s) and its rule(s)
*/
// Obtain the list of CSS style sheets
StyleSheetList sheets = document.getStyleSheets();
// Access the first sheet
AbstractCSSStyleSheet sheet = sheets.item(0);
// The first rule in the sheet
AbstractCSSRule rule = sheet.getCssRules().item(0);
// What kind of rule is it?
int ruleType = rule.getType();
// It is a style rule (CSSRule.STYLE_RULE)
Now we can cast to a StyleRule which gives us access to the selector list and the declared style.
Rule iterators
The same as above, but with a rule iterator:
/*
* It is possible to use iterators to retrieve the rules.
*/
sheet = sheets.item(0);
Iterator it = sheet.getCssRules().iterator();
// Assume it.hasNext() returns true
// Access the first rule in the sheet
rule = it.next();
// What kind of rule is it?
ruleType = rule.getType();
// It is a style rule (CSSRule.STYLE_RULE)
Sheet Visitors
You can also use the Visitor API to perform many of the tasks that can be achieved with the standard CSSOM, for example:
- acceptStyleRuleVisitor to visit style rules in a sheet.
- acceptDeclarationRuleVisitor to visit declaration rules in a sheet. In the terminology of this library, a declaration rule is a rule that contains any kind of declaration, be it property or descriptor declarations. For example, style, font-face and keyframe rules are all "declaration rules".
- acceptDescriptorRuleVisitor to visit declaration rules with descriptors within a sheet.
Those methods also apply to sheet lists:
- acceptStyleRuleVisitor to visit style rules in a list of sheets.
- acceptDeclarationRuleVisitor to visit declaration rules in a list of sheets.
- acceptDescriptorRuleVisitor to visit declaration rules with descriptors within a list of sheets.
With Visitors, you do not need to navigate the different rules yourself. For an example of its use, see Embedding SVG in HTML documents.
Dealing with selectors
If your use case requires inspecting the selectors, you will need to look at the NSAC api, starting with the Selector class.
// Cast
StyleRule styleRule = (StyleRule) rule;
// Obtain the selector list
SelectorList selist = styleRule.getSelectorList();
// First (and only) selector
Selector selector = selist.item(0);
// Selector type (which we can use to cast the selector)
SelectorType selType = selector.getSelectorType();
// For "div > .myClass" selType would be SelectorType.CHILD
// Cast to CombinatorSelector (see CHILD javadoc)
CombinatorSelector comb = (CombinatorSelector) selector;
// Obtain the two selectors that are combined by ">"
Selector firstSel = comb.getSelector();
SimpleSelector secondSel = comb.getSecondSelector();
// Examine the first selector
SelectorType firstSelType = firstSel.getSelectorType();
// Type is SelectorType.ELEMENT (div)
// Cast to ElementSelector (see ELEMENT javadoc)
ElementSelector elemSel = (ElementSelector) firstSel;
String elemName = elemSel.getLocalName();
// It is "div"
// Now the second selector
SelectorType secondSelType = secondSel.getSelectorType();
// Type is SelectorType.CONDITIONAL (.myClass)
// Cast to ConditionalSelector
ConditionalSelector condSel = (ConditionalSelector) secondSel;
Condition condition = condSel.getCondition();
ConditionType condType = condition.getConditionType();
// The condition type is ConditionType.CLASS
// Cast condition to AttributeCondition (as suggested by the CLASS javadoc)
AttributeCondition attrCond = (AttributeCondition) condition;
// Retrieve the condition (class) name
String cssClassName = attrCond.getValue();
// It is "myClass"
Low-level selector parsing
Sometimes one has to work with stand-alone selectors, for which you can use a NSAC parser:
CSSParser parser = new CSSParser();
SelectorList selist = parser.parseSelectors("a:not([href]):not([tabindex]):focus,pre,.myClass span");
Note: you should avoid stand-alone parsing namespaced selectors with parseSelectors
and equivalent single-argument methods in CSSParser
, as the namespace prefixes
won't map to any namespace URI. See parseSelectors(String,Parser.NamespaceMap) for a solution to the issue.
Using the declared styles
In the previous example we got the style rule in a styleRule
variable.
Now we use it to obtain the declared style with getStyle()
and examine the declared properties:
// Obtain the declared style from the rule
AbstractCSSStyleDeclaration style = styleRule.getStyle();
// Obtain the number of properties
int pCount = style.getLength();
// Two properties
/*
* The first property
*/
// Retrieve the name of the first property
String pname0 = style.item(0);
// pname0 is "font-size"
// Obtain the value of "font-size"
StyleValue fontSize = style.getPropertyCSSValue("font-size");
// Is it a length?
SyntaxParser synparser = new SyntaxParser();
CSSValueSyntax syntaxLength = synparser.parseSyntax("<length>");
Match match0 = fontSize.matches(syntaxLength);
// Match.TRUE: yes it is a length
// Let's check the primitive type
CSSValue.Type primiType0 = fontSize.getPrimitiveType();
// CSSValue.Type.NUMERIC: It is numeric
// Obtain the CSS unit and numeric value
NumberValue numericValue = (NumberValue) fontSize;
short unit = numericValue.getUnitType();
// Unit is typographic points (CSSUnit.CSS_PT)
float floatVal = numericValue.getFloatValue(unit);
// Value is 14 (14pt)
// Change the value to 23px (could use any length unit)
numericValue.setFloatValue(CSSUnit.CSS_PX, 23f);
/*
* The second property
*/
// Retrieve the name of the second property
String pname1 = style.item(1);
// pname1 is "color"
// Obtain the value of "color"
StyleValue color = style.getPropertyCSSValue("color");
// Let's check the global type
CSSValue.CssType type1 = color.getCssValueType();
// It is a CSSValue.CssType.PROXY, which means that it is either a
// custom property value (it is not) or a type not known in advance
// But may it be a color?
CSSValueSyntax syntaxColor = synparser.parseSyntax("<color>");
Match match1 = color.matches(syntaxColor);
// Gives Match.PENDING: yes it could be a color, but we do not know for sure
// until the value is computed
// Check the primitive type
CSSValue.Type primiType1 = color.getPrimitiveType();
// It is a var() function (CSSValue.Type.VAR)
// Obtain the custom property name
VarValue varValue = (VarValue) color;
String customPropertyName = varValue.getName();
// Name is --myColor
// In this case we have a fallback value (otherwise next line returns null)
LexicalUnit lexUnit = varValue.getFallback();
// Let's see its unit type
LexicalType luType = lexUnit.getLexicalUnitType();
// It is a LexicalType.RGBCOLOR
// And the color is...
String strColor = lexUnit.getCssText();
// Is '#46f'
// Access the individual color components.
// RGB colors are accessed as a rgb() function, so we retrieve
// the function parameters as a doubly-linked list:
LexicalUnit firstComponent = lexUnit.getParameters();
// Let's see the lexical type to see how we access the value
LexicalType firstLexUnitType = firstComponent.getLexicalUnitType();
// It is a LexicalType.INTEGER (RGB components could be REAL and PERCENTAGE as well)
// Therefore we use getIntegerValue()
int color_R = firstComponent.getIntegerValue();
// Is 0x44 hex (68 decimal)
// Second component is the next in the linked list.
// Beware that if the color was specified with commas,
// like "rgb(68, 102, 255)", the next one could be a comma!
LexicalUnit secondComponent = firstComponent.getNextLexicalUnit();
int color_G = secondComponent.getIntegerValue();
// Is 0x66 (102 decimal)
// Third component
LexicalUnit thirdComponent = secondComponent.getNextLexicalUnit();
int color_B = thirdComponent.getIntegerValue();
// Is 0xff (255 decimal)
Now let's set another property using setProperty:
/*
* Set another property, with important priority
*/
style.setProperty("background-color", "#d0dfee7a", "important");
pCount = style.getLength();
// Now we have three properties
If you are updating any of the declared sheets —that is, the sheets returned by document.getStyleSheets()
—
with setProperty
while you are computing styles, the changes will not apply to the computed styles
until you update the cascade with a call to rebuildCascade().
Updating internal sheets
IMPORTANT: once we are done updating a style sheet, if the sheet is internal to the
document (that is, it is located inside a <style>
element), the actual
contents of the <style>
element will not be updated until you execute
normalize()
on that element node:
// Obtain the owner node
org.w3c.dom.Node styleNode = sheet.getOwnerNode();
// Which type is it?
short nodeType = styleNode.getNodeType();
// It is a ELEMENT_NODE (could also be a PROCESSING_INSTRUCTION_NODE)
// Get the name of the element
String nodeName = styleNode.getNodeName();
// It is "style", as expected
// Get the element content (the initial serialized style sheet)
String preContent = styleNode.getTextContent();
// Serialize the current style sheet into the inner text node
styleNode.normalize();
// Get the normalized element content (the current serialization)
String afterContent = styleNode.getTextContent();
// preContent and afterContent are different
Working with inline styles
Now we are going to obtain the inline style of an element, as given by the style
attribute.
In the next example, the inline style is supposed to contain the declaration of a custom property called
--myColor
with a value #54e
.
/*
* Access a style attribute (inline styles)
*/
// First obtain the desired element, for example:
CSSElement element = document.getElementById("someId");
// Now the inline style. It can be directly accessed
CSSStyleDeclaration inlineStyle = element.getStyle();
// How many properties are defined?
int inlinePCount = inlineStyle.getLength();
// Suppose that it is just one called --myColor
// Retrieve its name
String inlinePname0 = inlineStyle.item(0);
// It is "--myColor"
// Now get the value
CSSValue myColor = inlineStyle.getPropertyCSSValue(inlinePname0);
/*
* Handle the custom property in myColor
*/
// Get the general value type
CSSValue.CssType type = myColor.getCssValueType();
// Being a custom property, it must be a CssType.PROXY
// But is it (or could be) a color?
Match matchCP = myColor.matches(syntaxColor);
// Match.TRUE: Yes it is for sure!
// Let's see the primitive type, although...
CSSValue.Type primiType = myColor.getPrimitiveType();
// custom properties are *always* Type.LEXICAL values
LexicalValue lvColor = (LexicalValue) myColor;
// Can we know its final value type once it is processed?
Type finalType = lvColor.getFinalType();
// Yes, as suggested by the result of calling 'matches'
// ...it is a Type.COLOR
// Let's retrieve its value
LexicalUnit lexUnitCP = lvColor.getLexicalUnit();
// First see its unit type
LexicalType luTypeCP = lexUnitCP.getLexicalUnitType();
// It is a RGBCOLOR
// And the color is...
String strlexUnitCP = lexUnitCP.getCssText();
// Is '#54e'. We could also access its components
// Let's change the value of the custom property
// We want to set '#667'
inlineStyle.setProperty(inlinePname0, "#667", null);
// Check that we successfully assigned the new value:
String newInlineValue = inlineStyle.getPropertyValue(inlinePname0);
// Yes it is '#667' as we wanted
After changing an inline style you do not need to call any method (like how normalize()
was used for
internal sheets) to modify the document. The serialization of (inline) style attributes is always up to date.
The small drawback is that the style
attributes may not appear exactly as they were specified, but instead
according to the serialization given by this library (which can be tailored a bit, for example by customizing endInlinePropertyDeclaration() in your own StyleFormattingContext
, see CSS
style formatting for details).
Override styles
Override styles, that come after the author style sheet in the cascade algorithm, are not part of the formal standard but are supported by this library; they are like "hidden" inline styles.
To access the override style of an element, use CSSElement
's getOverrideStyle.
For example:
element.getOverrideStyle(null).setCssText("padding: 6pt;");
Override styles are defined at the DocumentCSS interface description.
Configuring the cascade
Depending on your use case, you may need to set the user
agent (UA) style sheet before starting to compute styles.
The library supports two different UA sheets, one for STRICT
('standards') mode and another for QUIRKS
.
To set either of those sheets, first obtain an instance of the factory that you are using:
// Instantiate the new factory or get it from an object that you are already using.
AbstractCSSStyleSheetFactory cssFactory = ...
If you are using the DOM4J classes, you may want to do:
AbstractCSSStyleSheetFactory cssFactory = XHTMLDocumentFactory.getInstance().getStyleSheetFactory();
If you are processing HTML, css4j's default HTML5 UA sheet (based on W3C/WHATWG recommendations) should be appropriate for you:
cssFactory.setDefaultHTMLUserAgentSheet();
But if you want to set your own UA sheet, first obtain a reference to the sheet:
BaseCSSStyleSheet sheet = cssFactory.getUserAgentStyleSheet(CSSDocument.ComplianceMode.STRICT);
This is assuming the STRICT
mode, i.e. that you use documents with a DOCTYPE
, otherwise use QUIRKS
(or you may want to set both UA sheets).
If the UA sheet already contains rules (it is empty by default), clean it:
sheet.getCssRules().clear();
And now load the new sheet:
Reader reader = ... [reads the UA sheet]
sheet.parseStyleSheet(reader, CSSStyleSheet.COMMENTS_IGNORE);
reader.close();
As the UA sheet's comments are rarely of interest at the OM level, they were ignored during the parse
process (notice the COMMENTS_IGNORE
flag).
Note: this implementation does not support important
style declarations in the UA sheet.
Setting the user style sheet
There is also the possibility to set a user style sheet (with 'user' origin) via setUserStyleSheet:
Reader reader = ... [reads the user sheet]
cssFactory.setUserStyleSheet(reader);
reader.close();
Both important
and normal declarations are supported in the user style sheet.
Media handling
Setting a target medium for computed styles
By default, computed styles only take into account generic styles that are common to all media. If you want to target a more specific medium,
you have to use the CSSDocument.setTargetMedium("medium")
method. For example, if your document has the following style sheets linked:
<link href="http://www.example.com/css/sheet.css" rel="stylesheet" type="text/css" />
<link href="http://www.example.com/css/sheet_for_print.css" rel="stylesheet" media="print" type="text/css" />
Computed styles will initially take into account only the "sheet.css" style sheet. However, if you execute the following method:
document.setTargetMedium("print");
Then all subsequently computed styles will account for the merged style sheet from "sheet.css" and "sheet_for_print.css".
This way to tie a document with a medium is not totally standard, as the W3C APIs would probably expect a DeviceFactory
-related object implementing the
ViewCSS
interface and referencing the document,
but this approach allows to isolate DOM logic inside DOM objects and keep the DeviceFactory
for media-specific information only.
Media queries
The library provides an object-oriented interface to access media queries. If you obtain a MediaQueryList from a style sheet or a factory object, you can handle it like in the following example, where we create a media query and then produce a style sheet tied to it:
// We instantiate a factory based on CSSDOMImplementation,
// but could do the same with any of the other factories
AbstractCSSStyleSheetFactory cssFactory = new CSSDOMImplementation();
/*
* Parsing a Media Query
*/
MediaQueryList mql = cssFactory.createMediaQueryList("screen and (600px <= width < 1200px)",
null);
// How many queries we got?
int numQueries = mql.getLength();
// One
// Get the first and only query
MediaQuery mediaQ = mql.getMediaQuery(0);
// The media type
String medium = mediaQ.getMediaType();
// It is "screen"
/*
* Have a look at the associated boolean condition(s)
*/
BooleanCondition cond = mediaQ.getCondition();
// The condition type
BooleanCondition.Type condType = cond.getType();
// It is BooleanCondition.Type.AND
// As the AND javadoc suggests, call getSubConditions()
List andConds = cond.getSubConditions();
// andConds.size() is 2
// The first operand of the AND
BooleanCondition cond1 = andConds.get(0);
// The condition type
BooleanCondition.Type cond1Type = cond1.getType();
// It is BooleanCondition.Type.PREDICATE
// Now, following the indication from the getCondition() javadoc
// we cast the predicate to a MediaQueryPredicate
MediaQueryPredicate predicate1 = (MediaQueryPredicate) cond1;
// predicate1.getPredicateType() is MediaQueryPredicate.MEDIA_TYPE
// predicate1.getName() is "screen"
// The second operand of the AND
BooleanCondition cond2 = andConds.get(1);
// The condition type
BooleanCondition.Type cond2Type = cond2.getType();
// It is BooleanCondition.Type.PREDICATE
// Again, following the indication from the getCondition() javadoc
// we cast the predicate to a MediaQueryPredicate
MediaQueryPredicate predicate2 = (MediaQueryPredicate) cond2;
// predicate2.getPredicateType() is MediaQueryPredicate.MEDIA_FEATURE
// predicate2.getName() is "width"
// Cast predicate2 to MediaFeature
MediaFeature feature = (MediaFeature) predicate2;
// feature.getRangeType() is MediaFeaturePredicate.FEATURE_LE_AND_LT
// Obtain the first value in the LE_AND_LT range
CSSTypedValue value = feature.getValue();
// value.getPrimitiveType() is Type.NUMERIC
// value.getUnitType() is CSSUnit.CSS_PX (pixels)
// Get the numeric value
float floatValue = value.getFloatValue(CSSUnit.CSS_PX);
// Value is 600 (px)
// Now the second value in the LE_AND_LT range
CSSTypedValue value2 = feature.getRangeSecondValue();
// value.getPrimitiveType() is Type.NUMERIC
// value.getUnitType() is CSSUnit.CSS_PX
// Get the numeric value
float floatValue2 = value2.getFloatValue(CSSUnit.CSS_PX);
// Value is 1200 (px)
// Finally, create a sheet attached to that query
AbstractCSSStyleSheet sheet = cssFactory.createStyleSheet(null, mql);
// The object returned by 'sheet.getMedia()' and the 'mql' variable
// would be the same one
Style sheet sets
The library supports alternative style sheets: see CSSDocument's methods enableStyleSheetsForSet, getStyleSheetSets, getSelectedStyleSheetSet and setSelectedStyleSheetSet. For example, if you have a document with these linked sheets:
<link href="http://www.example.com/commonsheet.css" rel="stylesheet" type="text/css" />
<link href="http://www.example.com/alter1.css" rel="alternate stylesheet" type="text/css" title="Alter 1" />
<link href="http://www.example.com/alter2.css" rel="alternate stylesheet" type="text/css" title="Alter 2" />
<link href="http://www.example.com/default.css" rel="stylesheet" type="text/css" title="Default" />
Initially, sheets 'alter1.css' and 'alter2.css' will not be used to compute styles. But then you can write code like the following:
String defset = document.getSelectedStyleSheetSet(); // Sets 'defset' to "Default"
document.setSelectedStyleSheetSet("Alter 1"); // Selects the set with title "Alter 1"
document.setSelectedStyleSheetSet("Alter 2"); // Selects the set with title "Alter 2"
These methods have been removed from the DOM standard unfortunately, but you can still read the specification at the CSSOM 5 December 2013 Working Draft.
Style sheet error checking
You can check for errors and warnings in the document's sheets using the non-standard getErrorHandler method. Example:
if (document.getStyleSheets().item(0).getErrorHandler().hasSacErrors())
... error processing / reporting
The merged style sheet obtained from the getStyleSheet
method has the merged error/warning state from the document's active sheets.
A typical source of errors are the non-compliant IE hacks, like prefixing property names with an asterisk (you may want to use the proper NSAC flags when creating the factory, see Compatibility with legacy browsers), or charset rules found in the wrong place.
Parsing a style sheet
Although document's style sheet fetching and parsing is automatic with this library (for sheets referenced from a document), it is possible to manually parse rules from a source stream with the CSSStyleSheet.parseStyleSheet(Reader, short) method:
Reader re = ...
sheet.parseStyleSheet(re, CSSStyleSheet.COMMENTS_AUTO);
When the second argument is COMMENTS_IGNORE, the comments in the source stream are ignored when parsing (see Accessing Style Sheet Comments).
Important notes:
- Parsing a style sheet won't produce a
DOMException
unless the error handler (which you can customize) does raise it. The new CSS rules found in the source stream are added to the already present ones, i.e. the sheet is not reset by this method (although the error handler is), so if you want to refill a sheet you need to clear the rules before parsing:
sheet.getCssRules().clear();
Security model
Linked style sheets accessed through DOM are automatically fetched, but if your LINK
element or @import
rule point to a file:
or jar:
URL, the style sheet won't be retrieved unless you set the documentURI
of your document to one of those URIs.
A similar reasoning applies to the contents of the href
attribute in the BASE
element. If you load a
document that contains a <base href="file:///some/path">
, that won't take effect until you call setDocumentURI()
to set a URI with a file:
or jar:
scheme. This prevents denial of service attacks that could cause thread starvation
(for example by linking to file:///dev/zero
) or deplete the pool of entropy in your server (file:///dev/random
),
as well as jar:
decompression bombs.
Compatibility with legacy browsers
Today's style sheets often contain non-conformant styles that target specific versions of old web browsers, like Internet Explorer. Several web sites contain information about that, including:
Although it could be argued whether those hacks should be used or not, the point is that actual style sheets do contain them, so this library supports them.
By default, a factory is configured to use a flagless NSAC parser which would produce an error on any of those non-standard constructs, but a set of compatibility flags can be specified in the constructors for the factory implementations. The different flags are documented in the NSAC javadocs.
The flags available at the time of this guide's update are the following:
STARHACK
. When set, the parser will handle asterisk-prefixed property names as accepted, normal names.IEVALUES
supports values ending with\9
or\0
, as well as progid filters and IE expressions.IEPRIO
allows values ending with the'!ie'
priority hack.IEPRIOCHAR
accepts values with an'!important!'
priority hack (note the'!'
at the end).
The object model manages these compatibility values in parallel to standard ones. For example, after parsing this declaration
with IEVALUES
set:
width: 900px; width: 890px\9;
its serialization would be identical (if the flag was set correctly):
width: 900px; width: 890px\9;
but the declaration's length shall be only 1
. And computed styles only use the standard values unless there are
no alternatives (no standard value was set). The workings are similar for IEPRIO
and IEPRIOCHAR
:
width: 890px !ie;
width: 890px !important!;
with the last one being handled as of important
priority. Values created by IEPRIOCHAR
are never used
in computed styles.
Instead, declarations including asterisk-prefixed property names (created by STARHACK
) always increase the declaration's
length. For example, the length of the following declaration would be 2
:
width: 900px;
*width: 890px;
If you want to use these flags at the NSAC level (instead of the Object Model), you may want to read the 'Parser Flags' section in the NSAC package description, as well as the documentation for the individual flags in Parser.Flag.
CSS style formatting
The serialization of the cssText
attribute in rules and
style declarations can be customized with an implementation
of the StyleFormattingContext interface.
You can set your StyleFormattingFactory
(which produces your customized formatting context) to the sheet factory with the CSSStyleSheetFactory.setStyleFormattingFactory
method, or subclass your style sheet factory and override the createDefaultStyleFormattingFactory method.
Look at the DefaultStyleFormattingContext class for an example of a formatting context implementation.
To customize the serialization of computed styles, you want to override the createComputedStyleFormattingContext() method. The convenience RGBStyleFormattingFactory serializes computed colors as RGB and may serve as a customization example.
String value formatting
There is also the possibility to customize the default serialization of string values, with the CSSStyleSheetFactory.setFactoryFlag(byte) method. You can set two flags that govern which quotation you prefer, or keep the default behaviour:
- Default: Try to keep the original quotation (single or double quotes), unless the alternative is more efficient.
- STRING_DOUBLE_QUOTE: Use double quotes unless single quotes are more efficient (when the string contains more double quotes than single).
- STRING_SINGLE_QUOTE: Use single quotes unless double quotes are more efficient (when the string contains more single quotes than double).
Minification
The library provides methods for minified serialization at different levels (values, declarations, rules, lists, etc) but one generally wants to work at the style sheet level, in which case a generic CSS minification method could look like the following:
import io.sf.carte.doc.dom.CSSDOMImplementation;
import io.sf.carte.doc.style.css.CSSStyleSheet;
import io.sf.carte.doc.style.css.nsac.Parser;
import io.sf.carte.doc.style.css.om.AbstractCSSStyleSheet;
import io.sf.carte.doc.style.css.om.AbstractCSSStyleSheetFactory;
public static String minifyCSS(String css) {
// Instantiate any style sheet factory, with parser flags allowing IE hacks
AbstractCSSStyleSheetFactory cssFactory = new CSSDOMImplementation(
EnumSet.allOf(Parser.Flag.class));
// Create an empty style sheet
AbstractCSSStyleSheet sheet = cssFactory.createStyleSheet(null, null);
// Parse and check for return value
try {
if (sheet.parseStyleSheet(new StringReader(css),
CSSStyleSheet.COMMENTS_IGNORE)) {
// Parsed without errors
return sheet.toMinifiedString();
}
} catch (IOException e) {
// Cannot happen with StringReader
}
// Error detected, return the source
return css;
}
Beware of YUI Compressor
For further minification, you could choose to apply a specialized minification utility to the output of
toMinifiedString()
, and YUI
Compressor was a popular choice. But
that
library is not maintained anymore and the latest release was done in 2013: if you decide to apply the
YUI Compressor anyway, beware that it will break calc()
expressions and other stuff.
Although there are a few post-2.4.8 updates that were applied to the Compressor's master
branch on its Github repository, that
code is completely broken: it does not compile and at least one of the new regular expressions is wrong.
Accessing style sheet comments
CSS style sheets often have comments, like:
/* This is a preceding comment */
p {color: blue; } /* This is a trailing comment */
(XML-style comments can also be present in a style sheet, but both NSAC and the CSSOM skip them.)
There is no standard CSSOM API for accessing comments in style sheets, but the CSSRule.getPrecedingComments() and CSSRule.getTrailingComments() methods are provided for that:
StringList pcomments = document.getStyleSheets().item(0).getCssRules().item(3).getPrecedingComments();
StringList tcomments = document.getStyleSheets().item(0).getCssRules().item(3).getTrailingComments();
Other API models were considered for object-model comments, like having a special type of comment rule, but stylesheet-level comments are often related to a rule and if that rule is moved or deleted, those stand-alone comments would have the potential to create a lot of confusion.
By default, comments are parsed with the COMMENTS_AUTO
mode, which should be appropriate for human-readable sheets like the one shown above. But a lot of sheets are serialized
in a way that there are no newline characters (or only a few). For these cases,
COMMENTS_PRECEDING could be used in
parseStyleSheet(Reader,short),
and all the comments will be considered as belonging to the next rule. With COMMENTS_IGNORE
,
all comments found while parsing the sheet will be ignored.
The comments preceding/trailing any rule will be included in the text returned by the sheet's AbstractCSSStyleSheet.toString()
and
toStyleString()
methods,
while other comments (located at places that cannot be easily related to a rule) are lost.
In css4j version 1.0, comments that were intended to apply to the previous rule may be assigned to the next one, but this is addressed in version 2.0 where NSAC 2.0 allows a more accurate approach.
Comments in the default HTML UA style sheet are not available, as the parser is instructed to ignore them when parsing.
Providing device information for style computation
One of the most important functionalities in the library is the ability to compute styles for a given element.
In practice, to obtain the 'computed' or 'used' values required for actual rendering, a box model implementation is needed, and also device information. The library provides a simple box model that could be used, but the details of the rendering device can be more difficult.
Depending on the use case, the target device may not be the same one where the library is running (and some exact details hence not available). To help in the computation, this library provides a few helper interfaces. The most important are:
- DeviceFactory. Delivers the relevant abstractions for a requested medium:
StyleDatabase
andCSSCanvas
(also provides the objects required by media queries to work).
- StyleDatabase. Provides medium-specific information like available fonts and colors.
- CSSCanvas. Has knowledge of medium-specific information that depends (or may depend) on a specific viewport, like supported media features. It is linked to a viewport, if there is any. This interface is used to determine the state of active pseudo-classes.
- Viewport. It represents a viewport defined as per the CSS specifications.
The differences between style databases and canvases can be subtle, and for some media features it could be argued that they belong to one or the other. The basic idea is that style databases should be relatively easy to implement for a given medium, while canvases are probably only going to exist if there is an actual rendering engine implemented.
For an example implementation of a DeviceFactory
and related classes, please check out
MyDeviceFactory
, MyStyleDatabase
and MyCanvas
in EchoSVG's CSSTranscodingHelper,
or AWTStyleDatabase in the css4j-awt
project.
Create an AWT font/color from a computed style (css4j-awt module)
Once you have a computed style, on systems where AWT is available you can create an AWT font or color
with the createFont
and getAWTColor
static methods found in the AWTHelper class:
CSSComputedProperties style = ...
java.awt.Font font = AWTHelper.createFont(style);
CSSTypedValue cssColor = (CSSTypedValue) style.getPropertyCSSValue("color");
java.awt.Color color = AWTHelper.getAWTColor(cssColor);
Note that AWTHelper.createFont
requires a computed style as argument, while the
AWTHelper.getAWTColor
method can create colors from any typed value that represents
a color, regardless of it coming from a computed style or a style declaration (the
getPropertyCSSValue
shown above does not require the style to be computed).
These classes and methods belong to the css4j-awt module (which is the only css4j module that has a dependency on AWT).
CSS3 support
CSS3 (defined as "all CSS after CSS2.1") is partially supported by the library; the following table summarizes the support (supporting generally means that it can decompose shorthands, initial values are known, the rules are in the Object Model, etc.):
| CSS3 Spec Name | Support | Observations |
|---|---|---|
| Animations 2 | Yes | Supports the @keyframes rule and decomposes the the animation
shorthand. |
| Background / Border 3 | Yes | |
| Color 4 | Yes | |
| Color 5 | Partial | Supports full level 4 but only color-mix() from level 5 (this is aligned with web browser
support at the time of writing). |
| Fonts 4 | Partial | Has the @font-face and @font-feature-values rules,
also decomposes the the font shorthand. |
| Media Queries 4 | Partial | Event handling with addListener/removeListener is not supported.
Relies on CSSCanvas implementations to match/unmatch media features. |
| Selectors 4 | Yes | |
| Lists and Counters 3 | Partial | Decomposes the list-style shorthand. Limited support by the simple box model.
|
| Multi-column Layout | Partial | Decomposes the columns shorthand. Not supported by the simple box model.
|
| Masking | Partial | Decomposes the mask shorthand. Not supported by the simple box model. |
| Transitions | Yes | Decomposes the transition shorthand. |
| Values 4 | Yes | Advanced attr() from level 5 also has early support. |
| Variables | Yes | var() is supported in computed styles. |
| CSS Properties and Values API | Yes | Full support (also in computed styles). |
| Grid / Template / Alignment | Partial | Legacy gap properties (grid-row-gap ,
grid-column-gap , and grid-gap ) are not supported, although the longhands
can be used if declared explicitly). Not supported by the simple box model. |
Pseudo-classes
The following pseudo-classes are supported by the library:
first-child
, last-child
, only-child
, nth-child()
, nth-last-child()
, first-of-type
,
last-of-type
, only-of-type
, nth-of-type()
, nth-last-of-type()
, dir
, lang
,
any-link
, link
, visited
, target
, root
, empty
, blank
,
disabled
, enabled
, read-write
, read-only
, is
, where
, has
,
not
, placeholder-shown
, default
, checked
and indeterminate
.
State pseudo-classes like hover
are supported through the
CSSCanvas.isActivePseudoClass(CSSElement, String) method.
Java™ Runtime Environment requirements
The classes in the binary packages have been compiled with a Java compiler with 1.8 compiler compliance level,
except for the module-info
file which targets Java 11. If you are stuck with Java 7, you may want to use css4j 1.3.1.


Hi there! I'm Amy. I graduated from the University of Minnesota with a degrees in Speech-Language-Hearing Sciences and Neuroscience. I'm enrolled in a full stack web development bootcamp, but currently I'm working as the Production Manager at a non-profit in Northeast Minneapolis that provides employment services to individuals with barriers to employment. In this role I lead the company's two assembly work floors as well as print production processes. I manage key accounts, and oversee the work floor coordinators to ensure the on-time delivery of high quality finished goods. While I enjoy all aspects of my job, my favorite part is seeing opportunities for process improvement, and being able to implement a change that will make our operation function more smoothly.
It was actually this desire to seek out inefficiencies and create positive improvements that brought me to my interest in web development. It's exciting to me to find a problem or opportunity for improvement and implement a system that addresses that problem, which in my opinion, is the heart and soul of web development. I also enjoy the collaborative process that comes with communal brainstorming and finding creative solutions to problems.


The Art of War
If you know the enemy and know yourself, you need not fear the result of a hundred battles.
If you know yourself but not the enemy, for every victory gained you will also suffer a defeat.
If you know neither the enemy nor yourself, you will succumb in every battle.
- If your enemy is secure at all points, be prepared for him. If he is in superior strength, evade him.
- If your opponent is temperamental, seek to irritate him.
- Pretend to be weak, that he may grow arrogant.
- If he is taking his ease, give him no rest.
- If his forces are united, separate them.
- If sovereign and subject are in accord, put division between them. Attack him where he is unprepared, appear where you are not expected.
- There are not more than five musical notes, yet the combinations of these five give rise to more melodies than can ever be heard.
- There are not more than five primary colours, yet in combination
- they produce more hues than can ever been seen.
- There are not more than five cardinal tastes, yet combinations of
- them yield more flavours than can ever be tasted.
Air Mode
This is an example with airmode option...
MaterialSummernote is a fork of Summernote wysiwyg editor
(See the Original API)
Edited by CK
There are some extra options
that you can pass to the constructor in materialSummernote:- defaultTextColor (used by "color" button to set the default text color)
- defaultBackColor (used by "color" button to set button's color default color)
- followingToolbar [default true] (makes the toolbar follow on window scroll)
MaterialSummernote is not just a conversion of Summernote from bootstrap to materialize,
it also contains some changes
It is provided with scss version of the stylesheet, if you use sass, to change style quickly
In this version, editor's functions that you see on this page are tested; other summernote functions such airmode, still need to be converted;
Constructor
The only difference from Summernote is that you have to call materialnote() instad of summernote().
IMPORTANT: in case of multiple editors on the same page, the id attribute must be provided (if you use airMode, the id is needed always):

Toolbar
MaterialNote uses a javascript function to keep always visible the toolbar during scrolling.
If you don't want this to be enabled, pass followingToolbar: false option to the constructor.
Paragraph buttons
The paragraph buttons are available in dropdown format like Summernote (['paragraph'] option in the toolbar array) or as separate buttons (['leftButton', 'centerButton', 'rightButton', 'justifyButton', 'outdentButton', 'indentButton']).
Code sample
This is the constructor used for the above example:
var toolbar = [
['style', ['style', 'bold', 'italic', 'underline', 'strikethrough', 'clear']],
['fonts', ['fontsize', 'fontname']],
['color', ['color']],
['undo', ['undo', 'redo', 'help']],
['ckMedia', ['ckImageUploader', 'ckVideoEmbeeder']],
['misc', ['link', 'picture', 'table', 'hr', 'codeview', 'fullscreen']],
['para', ['ul', 'ol', 'paragraph', 'leftButton', 'centerButton', 'rightButton', 'justifyButton', 'outdentButton', 'indentButton']],
['height', ['lineheight']],
];
$('.editor').materialnote({
toolbar: toolbar,
height: 550,
minHeight: 100,
defaultBackColor: '#e0e0e0'
});
All options and methods of the original Summernote's API are still valid, so you can read the Summernote guide page or its API reference.


Hello Im Sumit Maiti a Developer
Hello, I'm Sumit Maiti and im a Developer . We have a big team of two people me and my friend Swarup Das. We are the student of CS in west bengal India. We both are skilled in C,C++,C#,Python,HTML,Css,Js Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum aspernatur ad cupiditate! Necessitatibus ducimus ea eligendi odit, asperiores expedita nulla.


@(target: String, query: String, message: String, isAdmin: Boolean, setup: Boolean)(implicit context: gitbucket.core.controller.Context) @gitbucket.core.html.main("Search Results", None){ @org.codelibs.gitbucket.fess.html.sidebar("search", isAdmin) { @org.codelibs.gitbucket.fess.html.menu(target, 0, 0, 0, query){ @if(setup){
Setting is not completed yet.
If you are the administrator,
please install Fess and
follow the instructions.


Reshapes a data frame of cells (probably the output of sheets_cells()
) into
another data frame, i.e., puts it back into the shape of the source
spreadsheet. At the moment, this function exists primarily for testing
reasons. The flagship function read_sheet()
is what most users are looking
for. It is basically sheets_cells()
+ spread_sheet()
.
spread_sheet(df, col_names = TRUE, col_types = NULL, na = "", trim_ws = TRUE, guess_max = min(1000, max(df$row)))
| df | A data frame with one row per (nonempty) cell, integer variables
|
|---|---|
| col_names |
|
| col_types | Column types. Either |
| na | Character vector of strings to interpret as missing values. By default, blank cells are treated as missing data. |
| trim_ws | Logical. Should leading and trailing whitespace be trimmed from cell contents? |
| guess_max | Maximum number of data rows to use for guessing column types. |
A tibble in the shape of the original spreadsheet, but enforcing
user's wishes regarding column names, column types, NA
strings, and
whitespace trimming.
#>#>spread_sheet(df)#> # A tibble: 5 x 6 #> country continent year lifeExp pop gdpPercap #> <chr> <chr> <dbl> <dbl> <dbl> <dbl> #> 1 Algeria Africa 1952 43.1 9279525 2449. #> 2 Angola Africa 1952 30.0 4232095 3521. #> 3 Benin Africa 1952 38.2 1738315 1063. #> 4 Botswana Africa 1952 47.6 442308 851. #> 5 Burkina Faso Africa 1952 32.0 4469979 543.#>#>#> # A tibble: 5 x 6 #> country continent year lifeExp pop gdpPercap #> <chr> <chr> <dbl> <dbl> <dbl> <dbl> #> 1 Algeria Africa 1952 43.1 9279525 2449. #> 2 Angola Africa 1952 30.0 4232095 3521. #> 3 Benin Africa 1952 38.2 1738315 1063. #> 4 Botswana Africa 1952 47.6 442308 851. #> 5 Burkina Faso Africa 1952 32.0 4469979 543.


public interface SearchPlugin
| 限定符和类型 | 接口和说明 |
|---|---|
static class |
SearchPlugin.AggregationSpec
Specification for an
Aggregation . |
static class |
SearchPlugin.FetchPhaseConstructionContext
Context available during fetch phase construction.
|
static class |
SearchPlugin.PipelineAggregationSpec
Specification for a
PipelineAggregator . |
static class |
SearchPlugin.QuerySpec<T extends QueryBuilder>
Specification of custom
Query . |
static class |
SearchPlugin.RescorerSpec<T extends RescorerBuilder<T>> |
static class |
SearchPlugin.ScoreFunctionSpec<T extends ScoreFunctionBuilder<T>>
Specification of custom
ScoreFunction . |
static class |
SearchPlugin.SearchExtensionSpec<W extends NamedWriteable,P>
Specification of search time behavior extension like a custom
MovAvgModel or ScoreFunction . |
static class |
SearchPlugin.SearchExtSpec<T extends SearchExtBuilder>
Specification for a
SearchExtBuilder which represents an additional section that can be
parsed in a search request (within the ext element). |
static class |
SearchPlugin.SuggesterSpec<T extends SuggestionBuilder<T>>
Specification for a
Suggester . |
| 限定符和类型 | 方法和说明 |
|---|---|
default java.util.List<SearchPlugin.AggregationSpec> |
getAggregations()
The new
Aggregation s added by this plugin. |
default java.util.List<FetchSubPhase> |
getFetchSubPhases(SearchPlugin.FetchPhaseConstructionContext context)
The new
FetchSubPhase s defined by this plugin. |
default java.util.Map<java.lang.String,Highlighter> |
getHighlighters()
Get the
Highlighter s defined by this plugin. |
default java.util.List<SearchPlugin.SearchExtensionSpec<MovAvgModel,MovAvgModel.AbstractModelParser>> |
getMovingAverageModels()
The new
MovAvgModel s defined by this plugin. |
default java.util.List<SearchPlugin.PipelineAggregationSpec> |
getPipelineAggregations()
The new
PipelineAggregator s added by this plugin. |
default java.util.List<SearchPlugin.QuerySpec<?>> |
getQueries()
The new
Query s defined by this plugin. |
default java.util.List<SearchPlugin.RescorerSpec<?>> |
getRescorers()
The next
Rescorer s added by this plugin. |
default java.util.List<SearchPlugin.ScoreFunctionSpec<?>> |
getScoreFunctions()
The new
ScoreFunction s defined by this plugin. |
default java.util.List<SearchPlugin.SearchExtSpec<?>> |
getSearchExts()
The new
SearchExtBuilder s defined by this plugin. |
default java.util.List<java.util.function.BiConsumer<SearchRequest,SearchResponse>> |
getSearchResponseListeners()
The new search response listeners in the form of
BiConsumer s added by this plugin. |
default java.util.List<SearchPlugin.SearchExtensionSpec<SignificanceHeuristic,SignificanceHeuristicParser>> |
getSignificanceHeuristics()
The new
SignificanceHeuristic s defined by this plugin. |
default java.util.List<SearchPlugin.SuggesterSpec<?>> |
getSuggesters()
The new
Suggester s defined by this plugin. |
default java.util.List<SearchPlugin.ScoreFunctionSpec<?>> getScoreFunctions()
ScoreFunction
s defined by this plugin.default java.util.List<SearchPlugin.SearchExtensionSpec<SignificanceHeuristic,SignificanceHeuristicParser>> getSignificanceHeuristics()
SignificanceHeuristic
s defined by this plugin. SignificanceHeuristics are used by the
SignificantTerms
aggregation to pick which terms are significant for a given query.default java.util.List<SearchPlugin.SearchExtensionSpec<MovAvgModel,MovAvgModel.AbstractModelParser>> getMovingAverageModels()
MovAvgModel
s defined by this plugin. MovAvgModels are used by the MovAvgPipelineAggregator
to
model trends in data.default java.util.List<FetchSubPhase> getFetchSubPhases(SearchPlugin.FetchPhaseConstructionContext context)
FetchSubPhase
s defined by this plugin.default java.util.List<SearchPlugin.SearchExtSpec<?>> getSearchExts()
SearchExtBuilder
s defined by this plugin.default java.util.Map<java.lang.String,Highlighter> getHighlighters()
Highlighter
s defined by this plugin.default java.util.List<SearchPlugin.SuggesterSpec<?>> getSuggesters()
Suggester
s defined by this plugin.default java.util.List<SearchPlugin.QuerySpec<?>> getQueries()
Query
s defined by this plugin.default java.util.List<SearchPlugin.AggregationSpec> getAggregations()
Aggregation
s added by this plugin.default java.util.List<SearchPlugin.PipelineAggregationSpec> getPipelineAggregations()
PipelineAggregator
s added by this plugin.default java.util.List<SearchPlugin.RescorerSpec<?>> getRescorers()
Rescorer
s added by this plugin.default java.util.List<java.util.function.BiConsumer<SearchRequest,SearchResponse>> getSearchResponseListeners()
BiConsumer
s added by this plugin.
The listeners are invoked on the coordinating node, at the very end of the search request.
This provides a convenient location if you wish to inspect/modify the final response (took time, etc).
The BiConsumers are passed the original SearchRequest
and the final SearchResponse


--- layout: archive title: Zulip Chat Archive permalink: /stream/113489-new-members/topic/VScode.3A.20way.20to.20not.20auto.20put.20in.20.60).60.20.3F.html ---
Hi, my WingWare IDE does this too. I could probably fix it there, but I'm new to VScode. So when I'm typing (a : \real ...
it will insert a )
for me which causes me to have to move my hand over 5" to type the End key on the keyboard. I'd rather just type in )
myself for sake of speed.
look for auto closing brackets in the settings
You can also just type a )
if one is inserted to go over it
Thanks! Either one works. I'll do the second one
{% endraw %}Last updated: Apr 24 2020 at 19:02 UTC


---
layout: layouts/post.njk
title: "Faster and More Accessible: The New digitalocean.com"
permalink: /new-do/
date: '2016-08-17'
comments: true
tags:
- performance
- accessibility
- digitalocean
description: "We unified the site with our updated branding, and also focused on improving digitalocean.com's accessibility, organization, and performance."
link-out: https://www.digitalocean.com/company/blog/faster-and-more-accessible-the-new-digitaloceancom/
---
If you are not redirected, please visit this think!


Should you find yourself wanting to install emoncms from git having previously installed via the apt-get method, it is possible to "add" a git installed version and use existing settings and data.(normal precautions apply about backing up data etc) To start just clone emoncms as in the install guide
cd /var/
sudo chown pi /www
cd /www
git clone https://github.com/emoncms/emoncms.git
Alias /emoncms /var/www/emoncms
<Directory /var/www/emoncms>
Options FollowSymLinks
AllowOverride All
DirectoryIndex index.php
Order allow,deny
Allow from all
</Directory>
Any additional emoncms modules will also need to be re-cloned from git or copied from the APT version folders, then restart apache with
sudo /etc/init.d/apache2 restart
You should be up and running using the same login & data etc on the latest git version of emoncms
The apt version is still intact so you should be able to revert back to it by simply renaming "sites-available" entries
This is intended as a development tool and not an upgrade path, please beware of running multiple versions as some features and data may not be backwards-compatable. Since this is not a recommended path for upgrading it should only really be used if waiting for the apt version update isn't an option or you need a git version to contribute to development..
I have only just tried this myself and therefore not tested in great depth, if any issues arise I will post here, please feel free to do the same or add anything I've missed.
Switching from "apt" to "git" emonCMS
Submitted by pb66 on Sun, 20/07/2014 - 08:20Should you find yourself wanting to install emoncms from git having previously installed via the apt-get method, it is possible to "add" a git installed version and use existing settings and data.(normal precautions apply about backing up data etc) To start just clone emoncms as in the install guide
cd /var/
sudo chown pi /www
cd /www
git clone https://github.com/emoncms/emoncms.git
and copy across your existing settings file
cp /usr/share/emoncms/www/settings.php emoncms/settings.php
then to redirect from the "apt" version to the "git" rename apache2's existing "sites-available" entry
sudo mv /etc/apache2/sites-available/emoncms /etc/apache2/sites-available/emoncmsAPT
and create a new one
sudo nano /etc/apache2/sites-available/emoncms
containing
Alias /emoncms /var/www/emoncms
<Directory /var/www/emoncms>
Options FollowSymLinks
AllowOverride All
DirectoryIndex index.php
Order allow,deny
Allow from all
</Directory>
Any additional emoncms modules will also need to be re-cloned from git or copied from the APT version folders, then restart apache with
sudo /etc/init.d/apache2 restart
You should be up and running using the same login & data etc on the latest git version of emoncms
The apt version is still intact so you should be able to revert back to it by simply renaming "sites-available" entries
sudo mv /etc/apache2/sites-available/emoncms /etc/apache2/sites-available/emoncmsGIT
sudo mv /etc/apache2/sites-available/emoncmsAPT /etc/apache2/sites-available/emoncms
sudo /etc/init.d/apache2 restart
This is intended as a development tool and not an upgrade path, please beware of running multiple versions as some features and data may not be backwards-compatable. Since this is not a recommended path for upgrading it should only really be used if waiting for the apt version update isn't an option or you need a git version to contribute to development..
I have only just tried this myself and therefore not tested in great depth, if any issues arise I will post here, please feel free to do the same or add anything I've missed.
Paul


--- layout: post title: "Day 29 - Bar Brothers Workout" subtitle: "My weight today is less than 0.300kg than it was yesterday, yesterday ended in cardio training and I have slight ankle pain, but that won't stop me from exercising today." date: 2019-11-19 background: '/img/posts/intro-barbrothers.png' ---
Today's Bar Brothers workout includes upper body workout and especially for the arms, in addition to the workout I set myself is cardio workout and because of the ankle pain since yesterday, I decided to do the cardio on the ground, meaning the same movements just lying down,
Each set will contain 20 seconds and four sets per exercise, after half an hour or 40 minutes I did the Bar Brothers workout, plus doing a pullup with auxiliary cable, I have a black auxiliary cable at home and used it yesterday and I did feel it was quite helpful and yet I felt effortless Unusual and that's what I do today.
At the food level, I couldn't make chicken breast yesterday, I took a big salad and tuna, two apples and probably tea, I also have 0% fat yogurt, I realized that these yogurts make up the appetite, so maybe I could close for lunch.
As you can see from the pictures there may have been a slight improvement in my back and a clear change since I started, so that we can see this change better I decided to bring the pictures back from the beginning in this post, you can see a difference, it is not great but it is also progress.
Tonight I continued as much as I could and hope to see weight loss again tomorrow, I thank everyone who reads these posts and thank Lazar and Dawson for clearly instructing how to do every day training from the three months
Good night.


--- layout: post status: publish published: true title: Localized Date information in Spanish Change for .NET 2.0 author: display_name: Tomas Restrepo login: tomasr email<EMAIL_ADDRESS>url: http://winterdom.com/ author_login: tomasr author_email<EMAIL_ADDRESS>author_url: http://winterdom.com/ wordpress_id: 251 wordpress_url: http://winterdom.com/2005/10/localizeddateinformationinspanishchangefornet20 date: '2005-10-18 13:00:43 +0000' date_gmt: '2005-10-18 13:00:43 +0000' categories: - ".NET" tags: [] comments: - id: 185 author: Jose Luis Manners author_email<EMAIL_ADDRESS>author_url: http://www.josemanners.com date: '2005-10-24 09:13:51 +0000' date_gmt: '2005-10-24 09:13:51 +0000' content: |
Hello Tomas,
I actually disagree with you. The new way (i.e. "febrero") is the correct way to spell the date in Spanish as in: "24 de febrero de 2005". I think (and I'm sure you already know this) that they had capitalized because that's the English format. But you might be thinking in other scenarios that I haven't even consider here.
Best regards,
Jose Luis Manners
It turns out that for .NET 2.0 there were changes in localized names for months and week days in spanish cultures (es-CO, for example). They used to be capitalized ("Febrero") and now they are not ("febrero").
I logged this to see what the answer was, and, it turns out (not unexpectedly) it was by design. I really would like to know just what kind of usage scenarios they had in mind, as I personally feel the change is not very useful, and actually makes some scenarios harder; but I might be convinced otherwise if it makes other scenarios easier!


1 Samuel 22:20
And one of the sons of Ahimelech the son of Ahitub, named Abiathar, escaped, and fled after David.


--- layout: post title: Some updates date: 2009-08-11 10:32:45.000000000 +02:00 categories: [] tags: [] status: publish type: post published: true meta: _edit_last: '5236424' author: login: stricksucht email<EMAIL_ADDRESS>display_name: stricksucht first_name: '' last_name: '' ---
Once again, I'm a part-time non-knitter. Not because I finally realized that studying and taking the next exam is more important than constant progress of my WIPs. I'd love to be as reasonable as that!  So I had to put a stop to all of my projects for two weeks, and I really, really hope that I can pick up the needles after that.
Despite the fact that knitting is out of the question right now, I set my mind on another project: Another Seascape Stole, this one a Christmas gift, made from KnitPicks Shimmer in the Cumulus colourway, for a friend of mine. She's always so kind and supportive and I don't know what I would do without her, so I'm thinking this might be the best way to say "Thank you!". The yarn has already been ordered (along with the yarn for Mam's shawl) and should arrive by the end of this week.
What makes this knitting hiatus even harder for me is the fact that I finally got the yarn from Balitmore:
Two skeins Cascade Yarns Alpaca Lace in Amethyst Heather. This one's gorgeous, super-soft and quite irresistable.
One skein Conjoined Creations Pastimes, Too in Sky. I've already wound it to a ball and practiced the lace cast-on with this one. And now I know that I'll definitely use wooden needles because it is so slippery on the metal ones.
And last but not least, one skein of Criative Acres Black Suri. This one's actually got the names of the alpacas printed on the label that donated the fibres for the yarn - how cool is that?
And then, just this morning, I've made one of the greatest discoveries: I found a German yarn store with an online shop that offers a wide range of yarns from US brands like Cascade Yarns, Fleece Artist or Crystal Palace!! I was amazed. And very, very happy. This is like shopping paradise for me. But maybe I'm just obsessed... ;)


ExamineDesktops()
Syntax
Result = ExamineDesktops()Description
Retrieves information about all the desktops connected to the local computer. This function must be called before using the functions of this library the following functions: DesktopDepth(), DesktopFrequency(), DesktopHeight(), DesktopName() and DesktopWidth().
Parameters
None.
Return value
The number of desktops on success, zero otherwise.
Remarks
Typically, a standard user has only one desktop, but multi-screen users may have several desktops, each with their own resolution.
Example
MessageRequester("Desktop Information", "You have "+Str(ExamineDesktops())+" desktops")
See Also
DesktopDepth(), DesktopFrequency(), DesktopHeight(), DesktopName(), DesktopWidth()
Supported OS
All


Vendor Name:
WATERSHED INFORMATION TECHNOLOGY INC.
Reference Number:
6017671
Contract Date:
2015-25-05
Description of Work:
0473 INFORMATION TECH & TELECOMM CONSULTANTS
Contract Period:
2015-25-05 to 2017-31-05
Delivery Date:
2017-31-05
Original Contract Value:
$126,932.41
Current Contract Value:
$253,864.81
Comments:
This contract was competitively sourced using a Public Services and Procurement Canada procurement tool. This contract is a multi-year contract and includes one or more amendments.
Additional Comments:
Programmer Analyst
Former Public Servant in Receipt of a Pension under the Public Service Superannuation Act:
no


OpenFileDialog
and SaveFileDialog
PersistentSearch
MaterialWindow.TitleBarIcon
propertyTabControlAssist.TabHeaderAlignment
attached propertyOpenDirectoryDialog.ShowDialogAsync
methodsOpenFileDialog.ShowDialogAsync
methodsSaveFileDialog.ShowDialogAsync
methodsIStepper
interface to implement new features for steppersIStep
interface to implement new features for steppersMaterialWindow
for a Material Design like styled windowTabStripPlacement
in TabControl
stylesOpenMultipleDirectoriesControl
and OpenMultipleDirectoriesDialog
to select multiple directoriesOpenMultipleFilesControl
and OpenMultipleFilesDialog
to select multiple filesTabControlAssist.TabHeaderAlignment
will be replaced by TabControlAssist.TabHeaderHorizontalAlignment
MaterialDesignExtensions.LongPath
for supporting long file system paths on older Windows and .NET versionsSaveFileControl.ForceFileExtensionOfFileFilter`
property to enforce a file extension of the selected filterDateTime
conversion inside DateTimeAgoConverter
OpenDirectoryControl
and SaveFileControl
PaletteHelper
for changing the theme at runtimeNullReferenceException
in SideNavigation
before the template will be appliedThe configuration of Material Design Extensions changed in order to enable changing the theme at runtime. Please change your configuration according to App.xaml of the demo.
StepTitleHeaderControl
to use bindings in a XAML defined stepTabControl
styles to render it in Material DesignBitmapImageHelper
Dispatcher
in Autocomplete.AutocompleteSourceItemsChangedHandler()
TabControlStepper
OversizedNumberSpinner
IAutocompleteSourceChangingItems
to propagate source changes to Autocomplete
PathToLongException
SearchHint
and SearchIcon
properties for SearchBase
Stepper.ActiveStep
property in order to navigate by a data bindingStepper
separator color via the resource MaterialDesignStepperSeparator
Autocomplete
TextBoxSuggestions
AppBar
title in the prominent areaNullReferenceException
in BaseFileControl
and OpenDirectoryControl
IsBackEnabled
, IsCancelEnabled
and IsContinueEnabled
properties for StepButtonBar
Back
event and BackCommand
command for AppBar
OpenFileControl
and SaveFileControl
FileSelectedCommand
command for BaseFileControl
DirectorySelectedCommand
command for OpenDirectoryControl
AppBar
ExtraProminent
DenseExtraProminent
Medium
MediumProminent
MediumExtraProminent
Stepper
API
NavigationCanceledByValidation
event and NavigationCanceledByValidationCommand
commandContentAnimationsEnabled
property to enable or disable animationsPersistentSearch
SideNavigation
FileFiltersTypeConverter
FileDialogArguments.FilterIndex
OpenFileControl
, SaveFileControl
, OpenFileDialog
and SaveFileDialog
SaveFileControl
's text fieldItemsControl
instead of ListBox
inside the file system controls
ListBox.SelectionChanged
was raised several times without any explicit user input causing undesired behaviorOpenDirectoryControl
, OpenFileControl
and SaveFileControl
)FileSystemControl
and sub classesAppBar
control with basic behavior defined in the Material Design specificationStepper
API
ActiveStep
propertyActiveStepChangedEvent
ActiveStepChangedCommand
BackNavigationCommand
CancelNavigationCommand
ContinueNavigationCommand
StepNavigationCommand
Stepper.Steps
in the constructorStepper
via XAMLOpenDirectoryControl
and OpenDirectoryDialog
to select a directoryOpenFileControl
and OpenFileDialog
to select a file for openingSaveFileControl
and SaveFileDialog
to select a file for saving data intoListBox
template to render as a grid list from the Material Design specification


Stencil composed talk to eachother through DOM events.
To dispatch Custom DOM events up for other components to handle, use the @Event()
decorator.
import { Event, EventEmitter } from '@stencil/core';
...
export class TodoList {
@Event() todoCompleted: EventEmitter;
todoCompletedHandler(todo: Todo) {
this.todoCompleted.emit(todo);
}
}
The code above will dispatch a custom DOM event called todoCompleted
.
The Listen()
decorator is for listening and responding to DOM events from a child.
In the example below, assume that a child component, TodoList
, emits a todoCompleted
event using the EventEmitter
.
import { Listen } from '@stencil/core';
...
export class TodoApp {
@Listen('todoCompleted')
todoCompletedHandler(event: CustomEvent) {
console.log('Received the custom todoCompleted event: ', event.detail);
}
}
Handlers can also be registered for an event on a specific element. This is useful for listening to application-wide events. In the example below, we're going to listen for the escape key's keyup event.
import { Listen } from '@stencil/core';
...
export class TodoList {
@Listen('body:keyup.escape')
escapeKeyUp() {
console.log('the escape key was clicked');
}
}


This ice sculpture is someone cursed by the Ice Queen, frozen for all time.
Look around the piece and its surroundings.


Don't have
Telegram
yet? Try it now!
Context
Embed
View In Channel
<script async src="https://telegram.org/js/telegram-widget.js?15" data-telegram-post="chollometro/28542" data-width="100%"></script>
Copy


Welcome Oke Shakirat!
Last visit: 3:56pm, SaturdayMarch 30, 2019
Note that shown balances can't reflect Pending Payments
| Account names / numbers | Balance | Available Balance |
|---|---|---|
|
Current Account Oke Shakirat /<PHONE_NUMBER> |
₦150,000.00 |
₦150,000.00 |
|
Savings Account Oke Shakirat /<PHONE_NUMBER> |
₦150,000.00 |
₦150,000.00 |


Source: this website
{% csrf_token %}
{% if messages %}
{% for message in messages %}
- {{ message }}
{% endfor %}
{% endif %}
{{ form.non_field_errors }}
{% include "site_groups.html" with groups=source_groups editable=editable job_site_key="source" %}
{% if editable %}
{% else %}
Automated text conversion or indexing is scheduled or in progress. Please wait until they complete to upload or copy files.
{% endif %}
Target: {{ selected_target.name }}
{% if selected_target or unselected_targets %}
{% for site in unselected_targets %}
(change to {{ site.name }})
{% endfor %}
{% include "site_groups.html" with groups=target_groups editable=0 job_site_key=selected_target.key %}
Sections
Sections of the interpretive texts visible in the Text Viewer:
{% for doc in section_docs %}
{{ doc }}
{% for section in sections %}
{% endfor %}
{% endfor %}
MSS in alignment
Press CTRL (or Command key) and click to select/unselect an item
{% else %}
You cannot release data from this website.
To release data, go to the staging site.
If you are a developer/sysadmin,
you may want to define
DATA_RELEASE_AVAILABLE_TARGETS
in your local.py
{% endif %}


"""
PoissonProcessMethods module contains functions for simulating and estimating
nonhomogenous Poisson processes.
"""
import numpy as np
from scipy import optimize
from scipy import random
import unittest
import warnings
[docs]def sampleHomogeneousPP(l,N):
"""
This function samples from a homogenous Poisson process.
Parameters
----------
l : float
the rate of the Poisson process
N : int
the number of observations from the process
Returns
-------
eventTimes : array of shape (N,)
- the time at which the events occur
Notes
-----
There could be multiple observations occurring at the same time.
"""
interArrivalTimes = [int(random.expovariate(1./l)) for i in np.arange(N)]
eventTimes = np.cumsum(interArrivalTimes)
return(eventTimes)
[docs]def sampleEvents(intensity,dt):
"""
Generates a sequence of events based on a Poisson process with
a time-dependent intensity.
Parameters
----------
intensity : an array of
dt: float
the spacing between two evaluations of the intensity
Returns
-------
an array (same length as intensity)
= 1 - event occurs
= 0 - event does not occur
"""
u = np.random.uniform(size = len(intensity))
return(intensity*dt>u)
[docs]def sampleInhomogeneousPP(intensity,dt,I):
"""
Samples time events on an interval [0,N)
according to an inhomogeneous Poisson process with
conditional intensity lambda
Parameters
----------
intensity : array
I : time interval [0,N]
"""
Lambda = sum(intensity)*dt
n = np.random.poisson(Lambda)
u = np.random.uniform(0,I[1],size = n)
#TODO need inverse
print ('Need to calculate the inverse of the intensity')
raise KeyboardInterrupt
[docs]def samplePiecewiseConstantPP(intensity,dt):
"""
Samples observations from a Poisson process with a piecewise-constant
intensity.
Parameters
----------
intensity : 1D array
the intensity evaluated at each bin
dt : float
the length of the bin
Returns
-------
y : 1D array (same shape as intensity)
the number of events in each bin
"""
y = np.apply_along_axis(np.random.poisson,0,l*dt)
return(y)
[docs]def poissonRegression(X,y,theta_0,dt=1,f = 'exp',method = 'L-BFGS-B'):
""" poissonRegression computes an estimate for the coefficients theta
Parameters
----------
X : a 2D array of covariates
y : a 1D array of outputs
dt : the spacing between the observations
theta_0 : initial guess
f : str or callable
The inverse link function: default is exp, but one can pass any function.
! Some functions may break the convergence of the algorithm.
Returns
-------
theta_MLE : array
Example
-------
>>> theta = np.random.normal(size = (2,))
>>> X = 0.1*np.random.normal(size = (2,1000))
>>> l = np.exp(np.dot(X.T,theta))
>>> Y = sampleEvents(l,0.01)
>>> theta_MLE = poissonRegression(X,Y,dt,np.zeros(theta.shape))
Notes
------
- provide a model structure to change
- index of columns to use (factors)
- the pdf (assuming independence of bins: use transition density otherwise)
- information about dt
- provide statistics for the fit of the regression?
"""
def negLogL(theta,X,y,dt,f):
"""
theta : parameters
X : covariates
y : response
dt : discretization step
f : nonlinear transformation of the input (default is exp)
"""
# calculate the intensity of the Poisson process
#intensity = np.exp(np.dot(X.T,theta))# for log link
if f == 'exp':
intensity = np.exp(np.dot(X.T,theta))
else:
intensity = f(np.dot(X.T,theta))[0]
# bins with spikes and bins with no spikes
l = sum(intensity)*dt - sum(y*np.log(intensity))
return(l)
def grad(theta,X,y,dt,f):
"""
theta : parameters
X : covariates
y : response
dt : discretization step
f : nonlinear transformation of the input (default is exp)
(should return the function value and its derivative)
"""
if f == 'exp':
# log-link
intensity = np.exp(np.dot(X.T,theta))
g = np.dot(X,intensity)*dt - np.dot(X,y)
else:
intensity,d_intensity = f(np.dot(X.T,theta))
g = np.dot(X,d_intensity)*dt - np.dot(X,(y*intensity/d_intensity))
return(g)
#TODO
# def Hessian
opts = {'disp':True,'maxiter': 200}
theta_hat = optimize.minimize(negLogL,theta_0, jac = grad, args = (X,y,dt,f),options = opts,method = method).x
# theta_hat = optimize.minimize(negLogL,theta_0, args = (X,y,dt),options = opts).x
return(theta_hat)
[docs]class testPoissonProcessMethods(unittest.TestCase):
[docs] def test_passing_nonlinearity(self):
"""
This function tests the passing a user-defined inverse-link function.
Passing a user defined exponential function should coincide with the
default exponential function.
"""
theta = np.random.normal(size = (10,))
X = 0.1*np.random.normal(size = (10,100))
# generate spike trains according to the poisson process
l = np.exp(np.dot(X.T,theta))
dt = 0.01
Y = sampleEvents(l,dt)
def myExponential(x):
return(np.exp(x),np.exp(x))
theta_0 = np.zeros((X.shape[0]))
theta_hat1 = poissonRegression(X,Y,theta_0,0.1,myExponential)
theta_hat2 = poissonRegression(X,Y,theta_0,0.1,'exp')
#self.assertEqual(theta_hat1,theta_hat2)
np.testing.assert_array_almost_equal(theta_hat1,theta_hat2)
[docs] def test_estimation(self):
N = 10000
d = 2
theta = np.random.normal(size = (d,))
X = 0.1*np.random.normal(size = (d,N))
l = np.exp(np.dot(X.T,theta))
dt = 0.001
Y = sampleEvents(l,dt)
theta_0 = np.zeros(theta.shape)
theta_MLE = poissonRegression(X,Y,theta_0,dt)
error = sum(np.abs(theta_MLE - theta))
tol = 5*d
# print(error)
self.assertTrue(error < tol, msg = "Estimation failed with error tolerance = 5d")
[docs] def test_prediction(self):
"""
This function is testing the prediction when l = exp(theta).
In this case each observation comes from a Poisson distribution with
a rate theta_i so the estimate for theta will rely on whether there
was an event in the bin or not, which results in a good prediction
(though not so good estimation)
"""
N = 100
theta = np.random.normal(size = (N,))
X = np.eye(N)
l = np.exp(np.dot(X.T,theta))
dt = 0.1
Y = sampleEvents(l,dt)
theta_0 = np.zeros(theta.shape)
theta_MLE = poissonRegression(X,Y,theta_0,dt)
l_predicted = np.exp(np.dot(X.T,theta_MLE))
Y_predicted = sampleEvents(l_predicted,dt)
total = sum(Y+Y_predicted)
if total != 0:
error_rate = sum(np.abs(Y - Y_predicted)).astype('float64')/total
else:
error_rate = 0
warnings.warn('No events observed.')
tol = .1
# print('error_rate'+str(error_rate))
# print(sum(np.abs(Y - Y_predicted)))
# print(sum(Y+Y_predicted)/2.)
self.assertTrue(error_rate < tol)
[docs] def test_simulation(self):
"""
This function tests how good the simulation of the Poisson process is.
"""
N = 1000
intensity = 3*np.ones((N,))
y = sampleEvents(intensity,0.1)
tol = 0.1
self.assertTrue(np.sum(np.abs(sum(y).astype('Float64'))/len(intensity) - 0.3)<tol,msg = 'Incomplete test')
if __name__ == '__main__':
unittest.main()


--- layout: post title: "From North to South" subtitle: "New Zealand 2019" date: 2019-02-19 20:00:00 -0500 categories: [Travels] tags: [New Zealand] background: 'https://hwmckenzie.github.io/img/posts/nz2019/header.jpg' ---
A short post today, but a significant one to mark our departure from the North island and arrival on the South Island.
We arose early to catch the ferry which took us across Cook Strait and into Queen Charlotte sound. Lucky for me, the seas were classified as “light”, and in fact the trip was very smooth. We had a good view of Wellington as we left, and coming into the sound was neat as it is not very wide and the vegetation goes right down to the shore. It reminded me quite a lot of the crossing from Vancouver to Victoria, and was about the same length of trip.
Once in Picton we hopped on a bus for Nelson which would be our home base for walking the coastal track in Abel Tasman National Park. After our walk we had a whole day in Nelson so we’ll describe the town more in that post. Suffice to say, we arrived at our Airbnb and met our host Julie. In this case we had a room in Julie’s house and were sharing the bathroom. As Julie was on the older side and very friendly, it sort of felt like we were staying with our grandmother. Off to sleep thinking of what we would see on our hike.
Chris & Hannah


We will show two examples using the advanced features of the debugger.
The first example defines a hide_exit(Pred)
predicate,
which will hide the Exit port for Pred
(i.e. it will
silently proceed), provided the current goal was already
ground at the Call port, and nothing was traced inside the
given invocation. The hide_exit(Pred)
goal creates two
spypoints for predicate Pred
:
:- meta_predicate hide_exit(:). hide_exit(Pred) :- add_breakpoint([pred(Pred),call]- true(save_groundness), _), add_breakpoint([pred(Pred),exit,true(hide_exit)]-hide, _).
The first spypoint is applicable at the Call port, and it
calls save_groundness
to check if the given invocation was
ground, and if so, it stores a term hide_exit(ground)
in the goal_private
attribute of the invocation.
save_groundness :- execution_state([goal(_:G),goal_private(Priv)]), ground(G), !, memberchk(hide_exit(ground), Priv). save_groundness.
The second spypoint created by hide_exit/1
is applicable at
the Exit port and it checks whether the hide_exit/0
condition is true. If so, it issues a hide
action, which is a
breakpoint macro expanding to [silent,proceed]
.
hide_exit :- execution_state([inv(I),max_inv(I),goal_private(Priv)]), memberchk(hide_exit(Ground), Priv), Ground == ground.
Here, hide_exit
encapsulates the tests that the invocation number
be the same as the last invocation number used (max_inv
), and
that the goal_private
attribute of the invocation be identical to
ground
. The first test ensures that nothing was traced inside the
current invocation.
If we load the above code, as well as the small example below,
the following interaction, discussed below, can take place. Note that the
hide_exit
predicate is called with the _:_
argument, resulting in generic spypoints being created.
| ?- consult(user). | cnt(0) :- !. | cnt(N) :- N > 0, N1 is N-1, cnt(N1). | ^D % consulted user in module user, 0 msec 424 bytes | ?- hide_exit(_:_), trace, cnt(1). % The debugger will first zip -- showing spypoints (zip) % Generic spypoint added, BID=1 % Generic spypoint added, BID=2 % The debugger will first creep -- showing everything (trace) # 1 1 Call: cnt(1) ? c # 2 2 Call: 1>0 ? c # 3 2 Call: _2019 is 1-1 ? c 3 2 Exit: 0 is 1-1 ? c # 4 2 Call: cnt(0) ? c 1 1 Exit: cnt(1) ? c % trace | ?-
Invocation 1 is ground, its Exit port is not hidden, because further goals were traced inside it. On the other hand, Exit ports of ground invocations 2 and 4 are hidden.
Our second example defines a predicate call_backtrace(Goal,
BTrace)
, which will execute Goal
and build a backtrace
showing the successful invocations executed during the solution of
Goal
.
The advantages of such a special backtrace over the one incorporated in the debugger are the following:
The call_backtrace/2
predicate is based on the advice
facility. It uses the variable accessible via the
private(_)
condition to store a mutable (see ref-lte-mut) holding the
backtrace. Outside the call_backtrace
predicate the mutable will have the value off
.
The example is a module-file, so that internal invocations can be
identified by the module name. We load the lists
library, because memberchk/2
will be used in the handling of the
private field.
:- module(backtrace, [call_backtrace/2]). :- use_module(library(lists)). :- meta_predicate call_backtrace(:, ?). call_backtrace(Goal, BTrace) :- Spec = [advice,call] -[true((goal(M:G),store_goal(M,G))),flit], ( current_breakpoint(Spec, _, on, _, _) -> B = [] ; add_breakpoint(Spec, B) ), call_cleanup(call_backtrace1(Goal, BTrace), remove_breakpoints(B)).
call_backtrace(Goal, BTrace)
is a meta-predicate, which
first sets up an appropriate advice-point for building the
backtrace. The advice-point will be activated at each Call
port and will call the store_goal/2
predicate with
arguments containing the module and the goal in
question. Note that the advice-point will not build a
procedure box (cf. the flit
command in the action part).
The advice-point will be added just once: any further (recursive)
calls to call_backtrace/2
will notice the existence of the
breakpoint and will skip the add_breakpoint/2
call.
Having ensured the appropriate advice-point exists,
call_backtrace/2
calls call_backtrace1/2
with a cleanup
operation that removes the breakpoint added, if any.
:- meta_predicate call_backtrace1(:, ?). call_backtrace1(Goal, BTrace) :- execution_state(private(Priv)), memberchk(backtrace_mutable(Mut), Priv), ( mutable(Mut) -> get_mutable(Old, Mut), update_mutable([], Mut) ; create_mutable([], Mut), Old = off ), call(Goal), get_mutable(BTrace, Mut), update_mutable(Old, Mut).
The predicate call_backtrace1/2
retrieves the private field
of the execution state and uses it to store a mutable, wrapped in
backtrace_mutable
. When first called within a top-level the
mutable is created with the value []
. In later calls the
mutable is re-initialized to []
. Having set up the
mutable, Goal
is called. In the course of the execution of
the Goal
the debugger will accumulate the backtrace in the
mutable. Finally, the mutable is read, its value is returned
in BTrace
, and it is restored to its old value (or off
).
store_goal(M, G) :- M \== backtrace, G \= call(_), execution_state(private(Priv)), memberchk(backtrace_mutable(Mut), Priv), mutable(Mut), get_mutable(BTrace, Mut), BTrace \== off, !, update_mutable([M:G|BTrace], Mut). store_goal(_, _).
store_goal/2
is the predicate called by the
advice-point, with the module and the goal as
arguments. We first ensure that calls from within the
backtrace
module and those of call/1
get
ignored. Next, the module qualified goal term is
prepended to the mutable value retrieved from the private field,
provided the mutable exists and its value is not off
.
Below is an example run, using a small program:
| ?- consult(user). | cnt(N):- N =< 0, !. | cnt(N) :- N > 0, N1 is N-1, cnt(N1). | ^D % consulted user in module user, 0 msec 424 bytes | ?- call_backtrace(cnt(1), B). % Generic advice point added, BID=1 % Generic advice point, BID=1, removed (last) B = [user:(0=<0),user:cnt(0),user:(0 is 1-1),user:(1>0),user:cnt(1)] | ?-
Note that the backtrace produced by call_backtrace/2
can
not contain any information regarding failed branches. For example, the
very first invocation within the above execution, 1 =< 0
, is
first put on the backtrace at its Call port, but this is
immediately undone because the goal fails. If you would like to
build a backtrace that preserves failed branches, you have to use
side-effects, e.g. dynamic predicates.
Further examples of complex breakpoint handling are contained in
library(debugger_examples)
.
This concludes the tutorial introduction of the advanced debugger features.


|
|||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |
See:
Description
| Interface Summary | |
|---|---|
| JavaDStreamLike<T,This extends JavaDStreamLike<T,This,R>,R extends JavaRDDLike<T,R>> | |
| JavaStreamingContextFactory | Factory interface for creating a new JavaStreamingContext |
| Class Summary | |
|---|---|
| JavaDStream<T> | A Java-friendly interface to DStream , the basic
abstraction in Spark Streaming that represents a continuous stream of data. |
| JavaInputDStream<T> | A Java-friendly interface to InputDStream . |
| JavaPairDStream<K,V> | A Java-friendly interface to a DStream of key-value pairs, which provides extra methods
like reduceByKey and join . |
| JavaPairInputDStream<K,V> | A Java-friendly interface to InputDStream of
key-value pairs. |
| JavaPairReceiverInputDStream<K,V> | A Java-friendly interface to ReceiverInputDStream , the
abstract class for defining any input stream that receives data over the network. |
| JavaReceiverInputDStream<T> | A Java-friendly interface to ReceiverInputDStream , the
abstract class for defining any input stream that receives data over the network. |
| JavaStreamingContext | A Java-friendly version of StreamingContext which is the main
entry point for Spark Streaming functionality. |
Java APIs for spark streaming.
|
|||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |


A collection of freely available daily workouts from various places on the Internet.
Recently (September, 2017) there have been an increase in the number of threads on /r/crossfit asking for programming tracks to follow. To reduce repeating answers, this page was quickly put together listing a number of well-known workout of the day (WOD) tracks that may help some readers.
The page is created by scraping WODs automatically from the respective owners' website once per day. All content is owned by the provider.
No problem; contact me and I will pull down your WOD.
Sure, if their WOD is freely available on their website please contact me and I'll add it to the scrape. Please note that sites that provide workouts which require you to login, or provide workouts through a paid subscription, will not be added.
Each WOD website is different, and so the scraper has to be taught whereabouts to look for the workout content. Contact me, let me know which gym you want and I will set it up for you. In the meantime, click on the gym name to be taken to the corresponding website.
The scraper runs thrice daily (0700AEST, 1400AEST and 2100AEST) and collects the most recent published workout from each source. Depending on the time you view this website, you may see the previous days' workout. Some sites publish a full day ahead, so you may see the next days' workout. Sources which are stale or do not publish regularly will show the last published workout.
This was knocked together quite quickly, but if it's popular, I'm more than happy to put some more effort in when time permits. Voice your approval or disapproval here or contact me and I'll see what I can do.
Built automatically at %build-date%


ISE Assistant Settings
ISE Active PAN Node
This should be an FQDN or IP address.
ISE MNT Node
This should be an FQDN or IP address.
ISE ERS Port
Default port for ISE ERS is 9060.
ISE User
Ensure this user has permissions to ISE ERS, and ISE ERS service is enabled in ISE Settings.
ISE Password
Save
Refresh Groups
Help
/
Update Notes


All of our open source projects are in use within the official Wix App! You can download the Wix App from the App Store And Google Play.