mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-06-08 13:12:10 +00:00
DATAES-114 - Migrate to Asciidoctor for reference documentation.
Converted existing docbook material to Asciidoctor and applied Spring styling.
This commit is contained in:
parent
b77b8ba0f2
commit
31797fad6e
4
pom.xml
4
pom.xml
@ -134,6 +134,10 @@
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>wagon-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.asciidoctor</groupId>
|
||||
<artifactId>asciidoctor-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -1,59 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||
<book xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<bookinfo>
|
||||
<title>Spring Data Elasticsearch</title>
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>BioMed Central</firstname>
|
||||
<surname>Development Team</surname>
|
||||
</author>
|
||||
</authorgroup>
|
||||
<legalnotice>
|
||||
<para>
|
||||
Copies of this document may be made for your own use and for
|
||||
distribution to others, provided that you do not
|
||||
charge any fee for
|
||||
such copies and further provided that each copy
|
||||
contains this
|
||||
Copyright Notice, whether
|
||||
distributed in print or electronically.
|
||||
</para>
|
||||
</legalnotice>
|
||||
|
||||
<copyright>
|
||||
<year>2013-2014</year>
|
||||
<holder>The original author(s)</holder>
|
||||
</copyright>
|
||||
</bookinfo>
|
||||
|
||||
<toc/>
|
||||
|
||||
<xi:include href="preface.xml"/>
|
||||
|
||||
<part id="reference">
|
||||
<title>Reference Documentation</title>
|
||||
|
||||
<xi:include href="https://raw.github.com/SpringSource/spring-data-commons/1.9.0.M1/src/docbkx/repositories.xml">
|
||||
<xi:fallback
|
||||
href="../../../spring-data-commons/src/docbkx/repositories.xml"/>
|
||||
</xi:include>
|
||||
|
||||
<xi:include href="reference/data-elasticsearch.xml"/>
|
||||
<xi:include href="reference/elasticsearch-misc.xml"/>
|
||||
</part>
|
||||
|
||||
<part id="appendix">
|
||||
<title>Appendix</title>
|
||||
<xi:include href="https://raw.github.com/SpringSource/spring-data-commons/1.9.0.M1/src/docbkx/repository-namespace-reference.xml">
|
||||
<xi:fallback
|
||||
href="../../../spring-data-commons/src/docbkx/repository-namespace-reference.xml"/>
|
||||
</xi:include>
|
||||
<xi:include href="https://raw.github.com/SpringSource/spring-data-commons/1.9.0.M1/src/docbkx/repository-query-keywords-reference.xml">
|
||||
<xi:fallback
|
||||
href="../../../spring-data-commons/src/docbkx/repository-query-keywords-reference.xml"/>
|
||||
</xi:include>
|
||||
</part>
|
||||
|
||||
</book>
|
@ -1,40 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||
<preface id="preface">
|
||||
<title>Preface</title>
|
||||
<para>The Spring Data Elasticsearch project applies core Spring
|
||||
concepts to
|
||||
the
|
||||
development of solutions using the Elasticsearch Search
|
||||
Engine.
|
||||
We have povided a "template" as a high-level abstraction for
|
||||
storing,querying,sorting and faceting documents. You will notice
|
||||
similarities
|
||||
to the Spring data solr and
|
||||
mongodb support in the Spring Framework.
|
||||
</para>
|
||||
<section id="project">
|
||||
<title>Project Metadata</title>
|
||||
<itemizedlist spacing="compact">
|
||||
<listitem>
|
||||
<para>
|
||||
Version Control -
|
||||
<ulink
|
||||
url="git://github.com/BioMedCentralLtd/spring-data-elasticsearch.git">
|
||||
git://github.com/BioMedCentralLtd/spring-data-elasticsearch.git
|
||||
</ulink>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section id="requirements">
|
||||
<title>Requirements</title>
|
||||
<para>
|
||||
Requires
|
||||
<ulink url="http://www.elasticsearch.org/download/">Elasticsearch</ulink>
|
||||
0.20.2 and above or optional dependency or not even that if you are
|
||||
using Embedded Node Client
|
||||
</para>
|
||||
</section>
|
||||
</preface>
|
@ -1,508 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||
<chapter id="elasticsearch.repositories">
|
||||
<title>Elasticsearch Repositories</title>
|
||||
<abstract>
|
||||
<para>This chapter includes details of the Elasticsearch repository
|
||||
implementation.
|
||||
</para>
|
||||
</abstract>
|
||||
<section id="elasticsearch.introduction">
|
||||
<title>Introduction</title>
|
||||
|
||||
<section id="elasticsearch.namespace">
|
||||
<title>Spring Namespace</title>
|
||||
|
||||
<para>
|
||||
The Spring Data Elasticsearch module contains a custom namespace
|
||||
allowing
|
||||
definition of repository beans as well as elements for
|
||||
instantiating
|
||||
a
|
||||
<classname>ElasticsearchServer</classname>
|
||||
.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Using the
|
||||
<code>repositories</code>
|
||||
element looks up Spring Data repositories as described in
|
||||
<xref linkend="repositories.create-instances"/>
|
||||
.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Setting up Elasticsearch repositories using Namespace</title>
|
||||
<programlisting language="xml"><?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
||||
http://www.springframework.org/schema/data/elasticsearch
|
||||
http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd">
|
||||
|
||||
<elasticsearch:repositories base-package="com.acme.repositories" />
|
||||
</beans></programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
Using the
|
||||
<code>Transport Client</code>
|
||||
or
|
||||
<code>Node Client</code>
|
||||
element registers an instance of
|
||||
<code>Elasticsearch Server</code>
|
||||
in the context.
|
||||
|
||||
<example>
|
||||
<title>Transport Client using Namespace</title>
|
||||
<programlisting language="xml"><?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
||||
http://www.springframework.org/schema/data/elasticsearch
|
||||
http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd">
|
||||
|
||||
<elasticsearch:transport-client id="client" cluster-nodes="localhost:9300,someip:9300" />
|
||||
</beans> </programlisting>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
<title>Node Client using Namespace</title>
|
||||
<programlisting language="xml"><?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
||||
http://www.springframework.org/schema/data/elasticsearch
|
||||
http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd">
|
||||
|
||||
<elasticsearch:node-client id="client" local="true"" />
|
||||
</beans> </programlisting>
|
||||
</example>
|
||||
</para>
|
||||
</section>
|
||||
<section id="elasticsearch.annotation">
|
||||
<title>Annotation based configuration</title>
|
||||
<para>The Spring Data Elasticsearch repositories support cannot only
|
||||
be
|
||||
activated through an XML namespace but also using an annotation
|
||||
through JavaConfig.
|
||||
</para>
|
||||
<example>
|
||||
<title>Spring Data Elasticsearch repositories using JavaConfig
|
||||
</title>
|
||||
<programlisting language="java">
|
||||
@Configuration
|
||||
@EnableElasticsearchRepositories(basePackages =
|
||||
"org/springframework/data/elasticsearch/repositories")
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
public ElasticsearchOperations elasticsearchTemplate() {
|
||||
return new ElasticsearchTemplate(nodeBuilder().local(true).node().client());
|
||||
}
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
The configuration above sets up an
|
||||
<classname>Embedded Elasticsearch Server</classname>
|
||||
which is used by the
|
||||
<classname>ElasticsearchTemplate</classname>
|
||||
. Spring Data Elasticsearch Repositories are activated using the
|
||||
<interfacename>@EnableElasticsearchRepositories</interfacename>
|
||||
annotation, which
|
||||
essentially carries the same attributes as the XML
|
||||
namespace does. If no
|
||||
base package is configured, it will use the
|
||||
one
|
||||
the configuration class
|
||||
resides in.
|
||||
</para>
|
||||
</example>
|
||||
</section>
|
||||
<section id="elasticsearch.cdi">
|
||||
<title>Elasticsearch Repositores using CDI</title>
|
||||
<para>The Spring Data Elasticsearch repositories can also be set up
|
||||
using CDI
|
||||
functionality.
|
||||
</para>
|
||||
<example>
|
||||
<title>Spring Data Elasticsearch repositories using JavaConfig
|
||||
</title>
|
||||
<programlisting language="java">class ElasticsearchTemplateProducer {
|
||||
|
||||
@Produces
|
||||
@ApplicationScoped
|
||||
public ElasticsearchOperations createElasticsearchTemplate() {
|
||||
return new ElasticsearchTemplate(nodeBuilder().local(true).node().client());
|
||||
}
|
||||
}
|
||||
|
||||
class ProductService {
|
||||
|
||||
private ProductRepository repository;
|
||||
|
||||
public Page<Product> findAvailableBookByName(String name, Pageable pageable) {
|
||||
return repository.findByAvailableTrueAndNameStartingWith(name, pageable);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setRepository(ProductRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
</section>
|
||||
<section id="elasticsearch.query-methods">
|
||||
<title>Query methods</title>
|
||||
<section id="elasticsearch.query-methods.finders">
|
||||
<title>Query lookup strategies</title>
|
||||
<para>
|
||||
The Elasticsearch module supports all basic query building
|
||||
feature as String,Abstract,Criteria or
|
||||
have
|
||||
it being derived from the
|
||||
method name.
|
||||
</para>
|
||||
|
||||
<simplesect>
|
||||
<title>Declared queries</title>
|
||||
<para>
|
||||
Deriving the query from the method name is not always sufficient
|
||||
and/or may result in unreadable method names. In this case one
|
||||
might make either use of
|
||||
<interfacename>@Query</interfacename>
|
||||
annotation (see
|
||||
<xref linkend="elasticsearch.query-methods.at-query"/>
|
||||
).
|
||||
</para>
|
||||
</simplesect>
|
||||
</section>
|
||||
|
||||
<section id="elasticsearch.query-methods.criterions">
|
||||
<title>Query creation</title>
|
||||
|
||||
<para>
|
||||
Generally the query creation mechanism for Elasticsearch works as
|
||||
described
|
||||
in
|
||||
<xref linkend="repositories.query-methods"/>
|
||||
. Here's a short example
|
||||
of what a Elasticsearch query method
|
||||
translates into:
|
||||
<example>
|
||||
<title>Query creation from method names</title>
|
||||
<programlisting language="java">public interface BookRepository extends Repository<Book, String>
|
||||
{
|
||||
List<Book> findByNameAndPrice(String name, Integer price);
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
The method name above will be translated into the following
|
||||
Elasticsearch json query
|
||||
</para>
|
||||
<programlisting>
|
||||
{ "bool" :
|
||||
{ "must" :
|
||||
[
|
||||
{ "field" : {"name" : "?"} },
|
||||
{ "field" : {"price" : "?"} }
|
||||
] } }
|
||||
</programlisting>
|
||||
</example>
|
||||
</para>
|
||||
<para>
|
||||
A list of supported keywords for Elasticsearch is shown below.
|
||||
<table>
|
||||
<title>Supported keywords inside method names</title>
|
||||
<tgroup cols="3">
|
||||
<colspec colwidth="1*"/>
|
||||
<colspec colwidth="2*"/>
|
||||
<colspec colwidth="3*"/>
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Keyword</entry>
|
||||
<entry>Sample</entry>
|
||||
<entry>Elasticsearch Query String</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<code>And</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByNameAndPrice</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : [ {"field" : {"name" : "?"}},
|
||||
{"field" : {"price" : "?"}} ]}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>Or</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByNameOrPrice</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"should" : [ {"field" : {"name" : "?"}},
|
||||
{"field" : {"price" : "?"}} ]}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>Is</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByName</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"field" : {"name" : "?"}}}}</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>Not</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByNameNot</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must_not" : {"field" : {"name" : "?"}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>Between</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByPriceBetween</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"range" : {"price" : {"from" :
|
||||
?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>LessThanEqual</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByPriceLessThan</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"range" : {"price" : {"from" :
|
||||
null,"to" : ?,"include_lower" : true,"include_upper" :
|
||||
true}}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>GreaterThanEqual</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByPriceGreaterThan</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"range" : {"price" : {"from" :
|
||||
?,"to" : null,"include_lower" : true,"include_upper" :
|
||||
true}}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>Before</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByPriceBefore</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"range" : {"price" : {"from" :
|
||||
null,"to" : ?,"include_lower" : true,"include_upper" :
|
||||
true}}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>After</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByPriceAfter</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"range" : {"price" : {"from" :
|
||||
?,"to" : null,"include_lower" : true,"include_upper" :
|
||||
true}}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>Like</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByNameLike</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"field" : {"name" : {"query" :
|
||||
"?*","analyze_wildcard" : true}}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>StartingWith</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByNameStartingWith</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"field" : {"name" : {"query" :
|
||||
"?*","analyze_wildcard" : true}}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>EndingWith</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByNameEndingWith</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"field" : {"name" : {"query" :
|
||||
"*?","analyze_wildcard" : true}}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>Contains/Containing</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByNameContaining</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"field" : {"name" : {"query" :
|
||||
"*?*","analyze_wildcard" : true}}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>In</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByNameIn(Collection<String>names)</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"bool" : {"should" : [ {"field" :
|
||||
{"name" : "?"}}, {"field" : {"name" : "?"}} ]}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>NotIn</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByNameNotIn(Collection<String>names)</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must_not" : {"bool" : {"should" : {"field" :
|
||||
{"name" : "?"}}}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>Near</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByStoreNear</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>Not Supported Yet !</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>True</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByAvailableTrue</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"field" : {"available" : true}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>False</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByAvailableFalse</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"bool" : {"must" : {"field" : {"available" : false}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>OrderBy</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>findByAvailableTrueOrderByNameDesc</code>
|
||||
</entry>
|
||||
<entry>
|
||||
<code>{"sort" : [{ "name" : {"order" : "desc"} }],"bool" :
|
||||
{"must" : {"field" : {"available" : true}}}}
|
||||
</code>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</para>
|
||||
</section>
|
||||
<section id="elasticsearch.query-methods.at-query">
|
||||
<title>Using @Query Annotation</title>
|
||||
<example>
|
||||
<title>
|
||||
Declare query at the method using the
|
||||
<interfacename>@Query</interfacename>
|
||||
annotation.
|
||||
</title>
|
||||
|
||||
<programlisting language="java">public interface BookRepository extends ElasticsearchRepository<Book,
|
||||
String> {
|
||||
@Query("{"bool" : {"must" : {"field" : {"name" : "?0"}}}}")
|
||||
Page<Book> findByName(String name,Pageable pageable);
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
</chapter>
|
@ -1,88 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||
<chapter id="elasticsearch.misc">
|
||||
<title>Miscellaneous Elasticsearch Operation Support</title>
|
||||
<abstract>
|
||||
<para>
|
||||
This chapter covers additional support for Elasticsearch operations
|
||||
that cannot be directly accessed via the repository
|
||||
interface.
|
||||
It is
|
||||
recommended to add those operations as custom
|
||||
implementation as
|
||||
described in
|
||||
<xref linkend="repositories.custom-implementations"/>
|
||||
.
|
||||
</para>
|
||||
</abstract>
|
||||
<section id="elasticsearch.misc.filter">
|
||||
<title>Filter Builder</title>
|
||||
<para>
|
||||
Filter Builder improves query speed.
|
||||
</para>
|
||||
<example>
|
||||
<programlisting language="java">
|
||||
private ElasticsearchTemplate elasticsearchTemplate;
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||
.withQuery(matchAllQuery())
|
||||
.withFilter(boolFilter().must(termFilter("id", documentId)))
|
||||
.build();
|
||||
Page<SampleEntity> sampleEntities =
|
||||
elasticsearchTemplate.queryForPage(searchQuery,SampleEntity.class);
|
||||
</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
<section id="elasticsearch.scan.and.scroll">
|
||||
<title>Using Scan And Scroll For Big Result Set</title>
|
||||
<para>
|
||||
Elasticsearch has scan and scroll feature for getting big result set
|
||||
in chunks.
|
||||
<interfacename>ElasticsearchTemplate</interfacename>
|
||||
has scan and scroll methods that can be used as below.
|
||||
</para>
|
||||
<example>
|
||||
<title>
|
||||
Using Scan and Scroll
|
||||
</title>
|
||||
<programlisting language="java">
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||
.withQuery(matchAllQuery())
|
||||
.withIndices("test-index")
|
||||
.withTypes("test-type")
|
||||
.withPageable(new PageRequest(0,1))
|
||||
.build();
|
||||
String scrollId = elasticsearchTemplate.scan(searchQuery,1000,false);
|
||||
List<SampleEntity> sampleEntities = new ArrayList<SampleEntity>();
|
||||
boolean hasRecords = true;
|
||||
while (hasRecords){
|
||||
Page<SampleEntity> page = elasticsearchTemplate.scroll(scrollId, 5000L , new ResultsMapper<SampleEntity>()
|
||||
{
|
||||
@Override
|
||||
public Page<SampleEntity> mapResults(SearchResponse response) {
|
||||
List<SampleEntity> chunk = new ArrayList<SampleEntity>();
|
||||
for(SearchHit searchHit : response.getHits()){
|
||||
if(response.getHits().getHits().length <= 0) {
|
||||
return null;
|
||||
}
|
||||
SampleEntity user = new SampleEntity();
|
||||
user.setId(searchHit.getId());
|
||||
user.setMessage((String)searchHit.getSource().get("message"));
|
||||
chunk.add(user);
|
||||
}
|
||||
return new PageImpl<SampleEntity>(chunk);
|
||||
}
|
||||
});
|
||||
if(page != null) {
|
||||
sampleEntities.addAll(page.getContent());
|
||||
hasRecords = page.hasNextPage();
|
||||
}
|
||||
else{
|
||||
hasRecords = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
</chapter>
|
File diff suppressed because it is too large
Load Diff
28
src/main/asciidoc/index.adoc
Normal file
28
src/main/asciidoc/index.adoc
Normal file
@ -0,0 +1,28 @@
|
||||
= Spring Data Elasticsearch
|
||||
BioMed Central Development Team
|
||||
:toc:
|
||||
:spring-data-commons-docs: https://raw.githubusercontent.com/spring-projects/spring-data-commons/issue/DATACMNS-551/src/main/asciidoc
|
||||
|
||||
{version}
|
||||
|
||||
(C) 2013-2014 The original author(s)
|
||||
|
||||
NOTE: _Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically._
|
||||
|
||||
include::preface.adoc[]
|
||||
|
||||
[[reference]]
|
||||
= Reference Documentation
|
||||
|
||||
:leveloffset: 1
|
||||
include::{spring-data-commons-docs}/repositories.adoc[]
|
||||
include::reference/data-elasticsearch.adoc[]
|
||||
include::reference/elasticsearch-misc.adoc[]
|
||||
|
||||
:leveloffset: 0
|
||||
:numbered!:
|
||||
[[appendix]]
|
||||
= Appendix
|
||||
|
||||
include::{spring-data-commons-docs}/repository-namespace-reference.adoc[]
|
||||
include::{spring-data-commons-docs}/repository-query-keywords-reference.adoc[]
|
15
src/main/asciidoc/preface.adoc
Normal file
15
src/main/asciidoc/preface.adoc
Normal file
@ -0,0 +1,15 @@
|
||||
[preface]
|
||||
= Preface
|
||||
|
||||
The Spring Data Elasticsearch project applies core Spring concepts to the development of solutions using the Elasticsearch Search Engine. We have povided a "template" as a high-level abstraction for storing,querying,sorting and faceting documents. You will notice similarities to the Spring data solr and mongodb support in the Spring Framework.
|
||||
|
||||
[[project]]
|
||||
== Project Metadata
|
||||
|
||||
* Version Control - `git://github.com/BioMedCentralLtd/spring-data-elasticsearch.git`
|
||||
|
||||
[[requirements]]
|
||||
== Requirements
|
||||
|
||||
Requires http://www.elasticsearch.org/download/[Elasticsearch] 0.20.2 and above or optional dependency or not even that if you are using Embedded Node Client
|
||||
|
288
src/main/asciidoc/reference/data-elasticsearch.adoc
Normal file
288
src/main/asciidoc/reference/data-elasticsearch.adoc
Normal file
@ -0,0 +1,288 @@
|
||||
[[elasticsearch.repositories]]
|
||||
= Elasticsearch Repositories
|
||||
|
||||
This chapter includes details of the Elasticsearch repository implementation.
|
||||
|
||||
[[elasticsearch.introduction]]
|
||||
== Introduction
|
||||
|
||||
[[elasticsearch.namespace]]
|
||||
=== Spring Namespace
|
||||
|
||||
The Spring Data Elasticsearch module contains a custom namespace allowing definition of repository beans as well as elements for instantiating a `ElasticsearchServer` .
|
||||
|
||||
Using the `repositories` element looks up Spring Data repositories as described in <<repositories.create-instances>> .
|
||||
|
||||
.Setting up Elasticsearch repositories using Namespace
|
||||
====
|
||||
[source,xml]
|
||||
----
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
||||
http://www.springframework.org/schema/data/elasticsearch
|
||||
http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd">
|
||||
|
||||
<elasticsearch:repositories base-package="com.acme.repositories" />
|
||||
|
||||
</beans>
|
||||
----
|
||||
====
|
||||
|
||||
Using the `Transport Client` or `Node Client` element registers an instance of `Elasticsearch Server` in the context.
|
||||
|
||||
.Transport Client using Namespace
|
||||
====
|
||||
[source,xml]
|
||||
----
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
||||
http://www.springframework.org/schema/data/elasticsearch
|
||||
http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd">
|
||||
|
||||
<elasticsearch:transport-client id="client" cluster-nodes="localhost:9300,someip:9300" />
|
||||
|
||||
</beans>
|
||||
----
|
||||
====
|
||||
|
||||
.Node Client using Namespace
|
||||
====
|
||||
[source,xml]
|
||||
----
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
||||
http://www.springframework.org/schema/data/elasticsearch
|
||||
http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd">
|
||||
|
||||
<elasticsearch:node-client id="client" local="true"" />
|
||||
|
||||
</beans>
|
||||
----
|
||||
====
|
||||
|
||||
[[elasticsearch.annotation]]
|
||||
=== Annotation based configuration
|
||||
|
||||
The Spring Data Elasticsearch repositories support cannot only be activated through an XML namespace but also using an annotation through JavaConfig.
|
||||
|
||||
.Spring Data Elasticsearch repositories using JavaConfig
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
@Configuration
|
||||
@EnableElasticsearchRepositories(basePackages = "org/springframework/data/elasticsearch/repositories")
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
public ElasticsearchOperations elasticsearchTemplate() {
|
||||
return new ElasticsearchTemplate(nodeBuilder().local(true).node().client());
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
The configuration above sets up an `Embedded Elasticsearch Server` which is used by the `ElasticsearchTemplate` . Spring Data Elasticsearch Repositories are activated using the `@EnableElasticsearchRepositories` annotation, which essentially carries the same attributes as the XML namespace does. If no base package is configured, it will use the one the configuration class resides in.
|
||||
|
||||
[[elasticsearch.cdi]]
|
||||
=== Elasticsearch Repositores using CDI
|
||||
|
||||
The Spring Data Elasticsearch repositories can also be set up using CDI functionality.
|
||||
|
||||
.Spring Data Elasticsearch repositories using JavaConfig
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
class ElasticsearchTemplateProducer {
|
||||
|
||||
@Produces
|
||||
@ApplicationScoped
|
||||
public ElasticsearchOperations createElasticsearchTemplate() {
|
||||
return new ElasticsearchTemplate(nodeBuilder().local(true).node().client());
|
||||
}
|
||||
}
|
||||
|
||||
class ProductService {
|
||||
|
||||
private ProductRepository repository;
|
||||
|
||||
public Page<Product> findAvailableBookByName(String name, Pageable pageable) {
|
||||
return repository.findByAvailableTrueAndNameStartingWith(name, pageable);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setRepository(ProductRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
[[elasticsearch.query-methods]]
|
||||
== Query methods
|
||||
|
||||
[[elasticsearch.query-methods.finders]]
|
||||
=== Query lookup strategies
|
||||
|
||||
The Elasticsearch module supports all basic query building feature as String,Abstract,Criteria or have it being derived from the method name.
|
||||
|
||||
==== Declared queries
|
||||
|
||||
Deriving the query from the method name is not always sufficient and/or may result in unreadable method names. In this case one might make either use of `@Query` annotation (see <<elasticsearch.query-methods.at-query>> ).
|
||||
|
||||
[[elasticsearch.query-methods.criterions]]
|
||||
=== Query creation
|
||||
|
||||
Generally the query creation mechanism for Elasticsearch works as described in <<repositories.query-methods>> . Here's a short example of what a Elasticsearch query method translates into:
|
||||
|
||||
.Query creation from method names
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
public interface BookRepository extends Repository<Book, String>
|
||||
{
|
||||
List<Book> findByNameAndPrice(String name, Integer price);
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
The method name above will be translated into the following Elasticsearch json query
|
||||
|
||||
[source]
|
||||
----
|
||||
{ "bool" :
|
||||
{ "must" :
|
||||
[
|
||||
{ "field" : {"name" : "?"} },
|
||||
{ "field" : {"price" : "?"} }
|
||||
]
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
A list of supported keywords for Elasticsearch is shown below.
|
||||
|
||||
[cols="1,2,3", options="header"]
|
||||
.Supported keywords inside method names
|
||||
|===
|
||||
| Keyword
|
||||
| Sample
|
||||
| Elasticsearch Query String| `And`
|
||||
| `findByNameAndPrice`
|
||||
| `{"bool" : {"must" : [ {"field" : {"name" : "?"}},
|
||||
{"field" : {"price" : "?"}} ]}}`
|
||||
|
||||
| `Or`
|
||||
| `findByNameOrPrice`
|
||||
| `{"bool" : {"should" : [ {"field" : {"name" : "?"}},
|
||||
{"field" : {"price" : "?"}} ]}}`
|
||||
|
||||
| `Is`
|
||||
| `findByName`
|
||||
| `{"bool" : {"must" : {"field" : {"name" : "?"}}}}`
|
||||
|
||||
| `Not`
|
||||
| `findByNameNot`
|
||||
| `{"bool" : {"must_not" : {"field" : {"name" : "?"}}}}`
|
||||
|
||||
| `Between`
|
||||
| `findByPriceBetween`
|
||||
| `{"bool" : {"must" : {"range" : {"price" : {"from" :
|
||||
?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}`
|
||||
|
||||
| `LessThanEqual`
|
||||
| `findByPriceLessThan`
|
||||
| `{"bool" : {"must" : {"range" : {"price" : {"from" :
|
||||
null,"to" : ?,"include_lower" : true,"include_upper" :
|
||||
true}}}}}`
|
||||
|
||||
| `GreaterThanEqual`
|
||||
| `findByPriceGreaterThan`
|
||||
| `{"bool" : {"must" : {"range" : {"price" : {"from" :
|
||||
?,"to" : null,"include_lower" : true,"include_upper" :
|
||||
true}}}}}`
|
||||
|
||||
| `Before`
|
||||
| `findByPriceBefore`
|
||||
| `{"bool" : {"must" : {"range" : {"price" : {"from" :
|
||||
null,"to" : ?,"include_lower" : true,"include_upper" :
|
||||
true}}}}}`
|
||||
|
||||
| `After`
|
||||
| `findByPriceAfter`
|
||||
| `{"bool" : {"must" : {"range" : {"price" : {"from" :
|
||||
?,"to" : null,"include_lower" : true,"include_upper" :
|
||||
true}}}}}`
|
||||
|
||||
| `Like`
|
||||
| `findByNameLike`
|
||||
| `{"bool" : {"must" : {"field" : {"name" : {"query" :
|
||||
"?*","analyze_wildcard" : true}}}}}`
|
||||
|
||||
| `StartingWith`
|
||||
| `findByNameStartingWith`
|
||||
| `{"bool" : {"must" : {"field" : {"name" : {"query" :
|
||||
"?*","analyze_wildcard" : true}}}}}`
|
||||
|
||||
| `EndingWith`
|
||||
| `findByNameEndingWith`
|
||||
| `{"bool" : {"must" : {"field" : {"name" : {"query" :
|
||||
"*?","analyze_wildcard" : true}}}}}`
|
||||
|
||||
| `Contains/Containing`
|
||||
| `findByNameContaining`
|
||||
| `{"bool" : {"must" : {"field" : {"name" : {"query" :
|
||||
"*?*","analyze_wildcard" : true}}}}}`
|
||||
|
||||
| `In`
|
||||
| `findByNameIn(Collection<String>names)`
|
||||
| `{"bool" : {"must" : {"bool" : {"should" : [ {"field" :
|
||||
{"name" : "?"}}, {"field" : {"name" : "?"}} ]}}}}`
|
||||
|
||||
| `NotIn`
|
||||
| `findByNameNotIn(Collection<String>names)`
|
||||
| `{"bool" : {"must_not" : {"bool" : {"should" : {"field" :
|
||||
{"name" : "?"}}}}}}`
|
||||
|
||||
| `Near`
|
||||
| `findByStoreNear`
|
||||
| `Not Supported Yet !`
|
||||
|
||||
| `True`
|
||||
| `findByAvailableTrue`
|
||||
| `{"bool" : {"must" : {"field" : {"available" : true}}}}`
|
||||
|
||||
| `False`
|
||||
| `findByAvailableFalse`
|
||||
| `{"bool" : {"must" : {"field" : {"available" : false}}}}`
|
||||
|
||||
| `OrderBy`
|
||||
| `findByAvailableTrueOrderByNameDesc`
|
||||
| `{"sort" : [{ "name" : {"order" : "desc"} }],"bool" :
|
||||
{"must" : {"field" : {"available" : true}}}}`
|
||||
|===
|
||||
|
||||
[[elasticsearch.query-methods.at-query]]
|
||||
=== Using @Query Annotation
|
||||
|
||||
.Declare query at the method using the `@Query` annotation.
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
public interface BookRepository extends ElasticsearchRepository<Book, String> {
|
||||
@Query("{"bool" : {"must" : {"field" : {"name" : "?0"}}}}")
|
||||
Page<Book> findByName(String name,Pageable pageable);
|
||||
}
|
||||
----
|
||||
====
|
72
src/main/asciidoc/reference/elasticsearch-misc.adoc
Normal file
72
src/main/asciidoc/reference/elasticsearch-misc.adoc
Normal file
@ -0,0 +1,72 @@
|
||||
[[elasticsearch.misc]]
|
||||
= Miscellaneous Elasticsearch Operation Support
|
||||
|
||||
This chapter covers additional support for Elasticsearch operations that cannot be directly accessed via the repository interface. It is recommended to add those operations as custom implementation as described in <<repositories.custom-implementations>> .
|
||||
|
||||
[[elasticsearch.misc.filter]]
|
||||
== Filter Builder
|
||||
|
||||
Filter Builder improves query speed.
|
||||
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
private ElasticsearchTemplate elasticsearchTemplate;
|
||||
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||
.withQuery(matchAllQuery())
|
||||
.withFilter(boolFilter().must(termFilter("id", documentId)))
|
||||
.build();
|
||||
|
||||
Page<SampleEntity> sampleEntities =
|
||||
elasticsearchTemplate.queryForPage(searchQuery,SampleEntity.class);
|
||||
----
|
||||
====
|
||||
|
||||
[[elasticsearch.scan.and.scroll]]
|
||||
== Using Scan And Scroll For Big Result Set
|
||||
|
||||
Elasticsearch has scan and scroll feature for getting big result set in chunks. `ElasticsearchTemplate` has scan and scroll methods that can be used as below.
|
||||
|
||||
.Using Scan and Scroll
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||
.withQuery(matchAllQuery())
|
||||
.withIndices("test-index")
|
||||
.withTypes("test-type")
|
||||
.withPageable(new PageRequest(0,1))
|
||||
.build();
|
||||
String scrollId = elasticsearchTemplate.scan(searchQuery,1000,false);
|
||||
List<SampleEntity> sampleEntities = new ArrayList<SampleEntity>();
|
||||
boolean hasRecords = true;
|
||||
while (hasRecords){
|
||||
Page<SampleEntity> page = elasticsearchTemplate.scroll(scrollId, 5000L , new ResultsMapper<SampleEntity>()
|
||||
{
|
||||
@Override
|
||||
public Page<SampleEntity> mapResults(SearchResponse response) {
|
||||
List<SampleEntity> chunk = new ArrayList<SampleEntity>();
|
||||
for(SearchHit searchHit : response.getHits()){
|
||||
if(response.getHits().getHits().length <= 0) {
|
||||
return null;
|
||||
}
|
||||
SampleEntity user = new SampleEntity();
|
||||
user.setId(searchHit.getId());
|
||||
user.setMessage((String)searchHit.getSource().get("message"));
|
||||
chunk.add(user);
|
||||
}
|
||||
return new PageImpl<SampleEntity>(chunk);
|
||||
}
|
||||
});
|
||||
if(page != null) {
|
||||
sampleEntities.addAll(page.getContent());
|
||||
hasRecords = page.hasNextPage();
|
||||
}
|
||||
else{
|
||||
hasRecords = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
356
src/main/resources/asciidoc/spring.css
Normal file
356
src/main/resources/asciidoc/spring.css
Normal file
@ -0,0 +1,356 @@
|
||||
/* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
|
||||
article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary { display: block; }
|
||||
audio, canvas, video { display: inline-block; }
|
||||
audio:not([controls]) { display: none; height: 0; }
|
||||
[hidden] { display: none; }
|
||||
html { background: #fff; color: #000; font-family: sans-serif; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; }
|
||||
body { margin: 0; }
|
||||
a:focus { outline: thin dotted; }
|
||||
a:active, a:hover { outline: 0; }
|
||||
h1 { font-size: 2em; margin: 0.67em 0; }
|
||||
abbr[title] { border-bottom: 1px dotted; }
|
||||
b, strong { font-weight: bold; }
|
||||
dfn { font-style: italic; }
|
||||
hr { -moz-box-sizing: content-box; box-sizing: content-box; height: 0; }
|
||||
mark { background: #ff0; color: #000; }
|
||||
code, kbd, pre, samp { font-family: monospace, serif; font-size: 1em; }
|
||||
pre { white-space: pre-wrap; }
|
||||
q { quotes: "\201C" "\201D" "\2018" "\2019"; }
|
||||
small { font-size: 80%; }
|
||||
sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
|
||||
sup { top: -0.5em; }
|
||||
sub { bottom: -0.25em; }
|
||||
img { border: 0; }
|
||||
svg:not(:root) { overflow: hidden; }
|
||||
figure { margin: 0; }
|
||||
fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; }
|
||||
legend { border: 0; padding: 0; }
|
||||
button, input, select, textarea { font-family: inherit; font-size: 100%; margin: 0; }
|
||||
button, input { line-height: normal; }
|
||||
button, select { text-transform: none; }
|
||||
button, html input[type="button"], input[type="reset"], input[type="submit"] { -webkit-appearance: button; cursor: pointer; }
|
||||
button[disabled], html input[disabled] { cursor: default; }
|
||||
input[type="checkbox"], input[type="radio"] { box-sizing: border-box; padding: 0; }
|
||||
input[type="search"] { -webkit-appearance: textfield; -moz-box-sizing: content-box; -webkit-box-sizing: content-box; box-sizing: content-box; }
|
||||
input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; }
|
||||
button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; }
|
||||
textarea { overflow: auto; vertical-align: top; }
|
||||
table { border-collapse: collapse; border-spacing: 0; }
|
||||
*, *:before, *:after { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; }
|
||||
html, body { font-size: 100%; }
|
||||
body { background: white; color: #222222; padding: 0; margin: 0; font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; font-weight: normal; font-style: normal; line-height: 1; position: relative; cursor: auto; }
|
||||
a:hover { cursor: pointer; }
|
||||
a:focus { outline: none; }
|
||||
img, object, embed { max-width: 100%; height: auto; }
|
||||
object, embed { height: 100%; }
|
||||
img { -ms-interpolation-mode: bicubic; }
|
||||
#map_canvas img, #map_canvas embed, #map_canvas object, .map_canvas img, .map_canvas embed, .map_canvas object { max-width: none !important; }
|
||||
.left { float: left !important; }
|
||||
.right { float: right !important; }
|
||||
.text-left { text-align: left !important; }
|
||||
.text-right { text-align: right !important; }
|
||||
.text-center { text-align: center !important; }
|
||||
.text-justify { text-align: justify !important; }
|
||||
.hide { display: none; }
|
||||
.antialiased, body { -webkit-font-smoothing: antialiased; }
|
||||
img { display: inline-block; vertical-align: middle; }
|
||||
textarea { height: auto; min-height: 50px; }
|
||||
select { width: 100%; }
|
||||
p.lead, .paragraph.lead > p, #preamble > .sectionbody > .paragraph:first-of-type p { font-size: 1.21875em; line-height: 1.6; }
|
||||
.subheader, #content #toctitle, .admonitionblock td.content > .title, .exampleblock > .title, .imageblock > .title, .videoblock > .title, .listingblock > .title, .literalblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, .sidebarblock > .title, .tableblock > .title, .verseblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title, .tableblock > caption { line-height: 1.4; color: #7a2518; font-weight: 300; margin-top: 0.2em; margin-bottom: 0.5em; }
|
||||
div, dl, dt, dd, ul, ol, li, h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6, pre, form, p, blockquote, th, td { margin: 0; padding: 0; direction: ltr; }
|
||||
a { color: #060; text-decoration: underline; line-height: inherit; }
|
||||
a:hover, a:focus { color: #040; }
|
||||
a img { border: none; }
|
||||
p { font-family: inherit; font-weight: normal; font-size: 1em; line-height: 1.6; margin-bottom: 1.25em; text-rendering: optimizeLegibility; }
|
||||
p aside { font-size: 0.875em; line-height: 1.35; font-style: italic; }
|
||||
h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { font-family: Georgia, "URW Bookman L", Helvetica, Arial, sans-serif; font-weight: normal; font-style: normal; color: #ba3925; text-rendering: optimizeLegibility; margin-top: 1em; margin-bottom: 0.5em; line-height: 1.2125em; }
|
||||
h1 small, h2 small, h3 small, #toctitle small, .sidebarblock > .content > .title small, h4 small, h5 small, h6 small { font-size: 60%; color: #e99b8f; line-height: 0; }
|
||||
h1 { font-size: 2.125em; }
|
||||
h2 { font-size: 1.6875em; }
|
||||
h3, #toctitle, .sidebarblock > .content > .title { font-size: 1.375em; }
|
||||
h4 { font-size: 1.125em; }
|
||||
h5 { font-size: 1.125em; }
|
||||
h6 { font-size: 1em; }
|
||||
hr { border: solid #dddddd; border-width: 1px 0 0; clear: both; margin: 1.25em 0 1.1875em; height: 0; }
|
||||
em, i { font-style: italic; line-height: inherit; }
|
||||
strong, b { font-weight: bold; line-height: inherit; }
|
||||
small { font-size: 60%; line-height: inherit; }
|
||||
code { font-family: Consolas, "Liberation Mono", Courier, monospace; font-weight: normal; color: #060; }
|
||||
ul, ol, dl { font-size: 1em; line-height: 1.6; margin-bottom: 1.25em; list-style-position: outside; font-family: inherit; }
|
||||
ul, ol { margin-left: 1.5em; }
|
||||
ul li ul, ul li ol { margin-left: 1.25em; margin-bottom: 0; font-size: 1em; }
|
||||
ul.square li ul, ul.circle li ul, ul.disc li ul { list-style: inherit; }
|
||||
ul.square { list-style-type: square; }
|
||||
ul.circle { list-style-type: circle; }
|
||||
ul.disc { list-style-type: disc; }
|
||||
ul.no-bullet { list-style: none; }
|
||||
ol li ul, ol li ol { margin-left: 1.25em; margin-bottom: 0; }
|
||||
dl dt { margin-bottom: 0.3125em; font-weight: bold; }
|
||||
dl dd { margin-bottom: 1.25em; }
|
||||
abbr, acronym { text-transform: uppercase; font-size: 90%; color: #222222; border-bottom: 1px dotted #dddddd; cursor: help; }
|
||||
abbr { text-transform: none; }
|
||||
blockquote { margin: 0 0 1.25em; padding: 0.5625em 1.25em 0 1.1875em; border-left: 1px solid #dddddd; }
|
||||
blockquote cite { display: block; font-size: inherit; color: #555555; }
|
||||
blockquote cite:before { content: "\2014 \0020"; }
|
||||
blockquote cite a, blockquote cite a:visited { color: #555555; }
|
||||
blockquote, blockquote p { line-height: 1.6; color: #6f6f6f; }
|
||||
.vcard { display: inline-block; margin: 0 0 1.25em 0; border: 1px solid #dddddd; padding: 0.625em 0.75em; }
|
||||
.vcard li { margin: 0; display: block; }
|
||||
.vcard .fn { font-weight: bold; font-size: 0.9375em; }
|
||||
.vevent .summary { font-weight: bold; }
|
||||
.vevent abbr { cursor: auto; text-decoration: none; font-weight: bold; border: none; padding: 0 0.0625em; }
|
||||
@media only screen and (min-width: 768px) { h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { line-height: 1.4; }
|
||||
h1 { font-size: 2.75em; }
|
||||
h2 { font-size: 2.3125em; }
|
||||
h3, #toctitle, .sidebarblock > .content > .title { font-size: 1.6875em; }
|
||||
h4 { font-size: 1.4375em; } }
|
||||
.print-only { display: none !important; }
|
||||
@media print { * { background: transparent !important; color: #000 !important; box-shadow: none !important; text-shadow: none !important; }
|
||||
a, a:visited { text-decoration: underline; }
|
||||
a[href]:after { content: " (" attr(href) ")"; }
|
||||
abbr[title]:after { content: " (" attr(title) ")"; }
|
||||
.ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; }
|
||||
pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }
|
||||
thead { display: table-header-group; }
|
||||
tr, img { page-break-inside: avoid; }
|
||||
img { max-width: 100% !important; }
|
||||
@page { margin: 0.5cm; }
|
||||
p, h2, h3, #toctitle, .sidebarblock > .content > .title { orphans: 3; widows: 3; }
|
||||
h2, h3, #toctitle, .sidebarblock > .content > .title { page-break-after: avoid; }
|
||||
.hide-on-print { display: none !important; }
|
||||
.print-only { display: block !important; }
|
||||
.hide-for-print { display: none !important; }
|
||||
.show-for-print { display: inherit !important; } }
|
||||
table { background: white; margin-bottom: 1.25em; border: solid 1px #dddddd; }
|
||||
table thead, table tfoot { background: whitesmoke; font-weight: bold; }
|
||||
table thead tr th, table thead tr td, table tfoot tr th, table tfoot tr td { padding: 0.5em 0.625em 0.625em; font-size: inherit; color: #222222; text-align: left; }
|
||||
table tr th, table tr td { padding: 0.5625em 0.625em; font-size: inherit; color: #222222; }
|
||||
table tr.even, table tr.alt, table tr:nth-of-type(even) { background: #f9f9f9; }
|
||||
table thead tr th, table tfoot tr th, table tbody tr td, table tr td, table tfoot tr td { display: table-cell; line-height: 1.6; }
|
||||
.clearfix:before, .clearfix:after, .float-group:before, .float-group:after { content: " "; display: table; }
|
||||
.clearfix:after, .float-group:after { clear: both; }
|
||||
*:not(pre) > code { font-size: 0.9375em; padding: 1px 3px 0; white-space: nowrap; background-color: #f2f2f2; border: 1px solid #cccccc; -webkit-border-radius: 4px; border-radius: 4px; text-shadow: none; }
|
||||
pre, pre > code { line-height: 1.4; color: inherit; font-family: Consolas, "Liberation Mono", Courier, monospace; font-weight: normal; }
|
||||
kbd.keyseq { color: #555555; }
|
||||
kbd:not(.keyseq) { display: inline-block; color: #222222; font-size: 0.75em; line-height: 1.4; background-color: #F7F7F7; border: 1px solid #ccc; -webkit-border-radius: 3px; border-radius: 3px; -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 2px white inset; box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 2px white inset; margin: -0.15em 0.15em 0 0.15em; padding: 0.2em 0.6em 0.2em 0.5em; vertical-align: middle; white-space: nowrap; }
|
||||
kbd kbd:first-child { margin-left: 0; }
|
||||
kbd kbd:last-child { margin-right: 0; }
|
||||
.menuseq, .menu { color: #090909; }
|
||||
p a > code:hover { color: #561309; }
|
||||
#header, #content, #footnotes, #footer { width: 100%; margin-left: auto; margin-right: auto; margin-top: 0; margin-bottom: 0; max-width: 62.5em; *zoom: 1; position: relative; padding-left: 0.9375em; padding-right: 0.9375em; }
|
||||
#header:before, #header:after, #content:before, #content:after, #footnotes:before, #footnotes:after, #footer:before, #footer:after { content: " "; display: table; }
|
||||
#header:after, #content:after, #footnotes:after, #footer:after { clear: both; }
|
||||
#header { margin-bottom: 2.5em; }
|
||||
#header > h1 { color: black; font-weight: normal; border-bottom: 1px solid #dddddd; margin-bottom: -28px; padding-bottom: 32px; }
|
||||
#header span { color: #6f6f6f; }
|
||||
#header #revnumber { text-transform: capitalize; }
|
||||
#header br { display: none; }
|
||||
#header br + span { padding-left: 3px; }
|
||||
#header br + span:before { content: "\2013 \0020"; }
|
||||
#header br + span.author { padding-left: 0; }
|
||||
#header br + span.author:before { content: ", "; }
|
||||
#toc { border-bottom: 3px double #ebebeb; padding-bottom: 1.25em; }
|
||||
#toc > ul { margin-left: 0.25em; }
|
||||
#toc ul.sectlevel0 > li > a { font-style: italic; }
|
||||
#toc ul.sectlevel0 ul.sectlevel1 { margin-left: 0; margin-top: 0.5em; margin-bottom: 0.5em; }
|
||||
#toc ul { list-style-type: none; }
|
||||
#toctitle { color: #7a2518; }
|
||||
@media only screen and (min-width: 1280px) { body.toc2 { padding-left: 20em; }
|
||||
#toc.toc2 { position: fixed; width: 20em; left: 0; top: 0; border-right: 1px solid #ebebeb; border-bottom: 0; z-index: 1000; padding: 1em; height: 100%; overflow: auto; }
|
||||
#toc.toc2 #toctitle { margin-top: 0; }
|
||||
#toc.toc2 > ul { font-size: .95em; }
|
||||
#toc.toc2 ul ul { margin-left: 0; padding-left: 1.25em; }
|
||||
#toc.toc2 ul.sectlevel0 ul.sectlevel1 { padding-left: 0; margin-top: 0.5em; margin-bottom: 0.5em; }
|
||||
body.toc2.toc-right { padding-left: 0; padding-right: 20em; }
|
||||
body.toc2.toc-right #toc.toc2 { border-right: 0; border-left: 1px solid #ebebeb; left: auto; right: 0; } }
|
||||
#content #toc { border-style: solid; border-width: 1px; border-color: #d9d9d9; margin-bottom: 1.25em; padding: 1.25em; background: #f2f2f2; border-width: 0; -webkit-border-radius: 4px; border-radius: 4px; }
|
||||
#content #toc > :first-child { margin-top: 0; }
|
||||
#content #toc > :last-child { margin-bottom: 0; }
|
||||
#content #toc a { text-decoration: none; }
|
||||
#content #toctitle { font-weight: bold; font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; font-size: 1em; padding-left: 0.125em; }
|
||||
#footer { max-width: 100%; background-color: #222222; padding: 1.25em; }
|
||||
#footer-text { color: #dddddd; line-height: 1.44; }
|
||||
.sect1 { padding-bottom: 1.25em; }
|
||||
.sect1 + .sect1 { border-top: 3px double #ebebeb; }
|
||||
#content h1 > a.anchor, h2 > a.anchor, h3 > a.anchor, #toctitle > a.anchor, .sidebarblock > .content > .title > a.anchor, h4 > a.anchor, h5 > a.anchor, h6 > a.anchor { position: absolute; width: 1em; margin-left: -1em; display: block; text-decoration: none; visibility: hidden; text-align: center; font-weight: normal; }
|
||||
#content h1 > a.anchor:before, h2 > a.anchor:before, h3 > a.anchor:before, #toctitle > a.anchor:before, .sidebarblock > .content > .title > a.anchor:before, h4 > a.anchor:before, h5 > a.anchor:before, h6 > a.anchor:before { content: '\00A7'; font-size: .85em; vertical-align: text-top; display: block; margin-top: 0.05em; }
|
||||
#content h1:hover > a.anchor, #content h1 > a.anchor:hover, h2:hover > a.anchor, h2 > a.anchor:hover, h3:hover > a.anchor, #toctitle:hover > a.anchor, .sidebarblock > .content > .title:hover > a.anchor, h3 > a.anchor:hover, #toctitle > a.anchor:hover, .sidebarblock > .content > .title > a.anchor:hover, h4:hover > a.anchor, h4 > a.anchor:hover, h5:hover > a.anchor, h5 > a.anchor:hover, h6:hover > a.anchor, h6 > a.anchor:hover { visibility: visible; }
|
||||
#content h1 > a.link, h2 > a.link, h3 > a.link, #toctitle > a.link, .sidebarblock > .content > .title > a.link, h4 > a.link, h5 > a.link, h6 > a.link { color: #ba3925; text-decoration: none; }
|
||||
#content h1 > a.link:hover, h2 > a.link:hover, h3 > a.link:hover, #toctitle > a.link:hover, .sidebarblock > .content > .title > a.link:hover, h4 > a.link:hover, h5 > a.link:hover, h6 > a.link:hover { color: #a53221; }
|
||||
.imageblock, .literalblock, .listingblock, .verseblock, .videoblock { margin-bottom: 1.25em; }
|
||||
.admonitionblock td.content > .title, .exampleblock > .title, .imageblock > .title, .videoblock > .title, .listingblock > .title, .literalblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, .sidebarblock > .title, .tableblock > .title, .verseblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { text-align: left; font-weight: bold; }
|
||||
.tableblock > caption { text-align: left; font-weight: bold; white-space: nowrap; overflow: visible; max-width: 0; }
|
||||
table.tableblock #preamble > .sectionbody > .paragraph:first-of-type p { font-size: inherit; }
|
||||
.admonitionblock > table { border: 0; background: none; width: 100%; }
|
||||
.admonitionblock > table td.icon { text-align: center; width: 80px; }
|
||||
.admonitionblock > table td.icon img { max-width: none; }
|
||||
.admonitionblock > table td.icon .title { font-weight: bold; text-transform: uppercase; }
|
||||
.admonitionblock > table td.content { padding-left: 1.125em; padding-right: 1.25em; border-left: 1px solid #dddddd; color: #6f6f6f; }
|
||||
.admonitionblock > table td.content > :last-child > :last-child { margin-bottom: 0; }
|
||||
.exampleblock > .content { border-style: solid; border-width: 1px; border-color: #e6e6e6; margin-bottom: 1.25em; padding: 1.25em; background: white; -webkit-border-radius: 4px; border-radius: 4px; }
|
||||
.exampleblock > .content > :first-child { margin-top: 0; }
|
||||
.exampleblock > .content > :last-child { margin-bottom: 0; }
|
||||
.exampleblock > .content h1, .exampleblock > .content h2, .exampleblock > .content h3, .exampleblock > .content #toctitle, .sidebarblock.exampleblock > .content > .title, .exampleblock > .content h4, .exampleblock > .content h5, .exampleblock > .content h6, .exampleblock > .content p { color: #333333; }
|
||||
.exampleblock > .content h1, .exampleblock > .content h2, .exampleblock > .content h3, .exampleblock > .content #toctitle, .sidebarblock.exampleblock > .content > .title, .exampleblock > .content h4, .exampleblock > .content h5, .exampleblock > .content h6 { line-height: 1; margin-bottom: 0.625em; }
|
||||
.exampleblock > .content h1.subheader, .exampleblock > .content h2.subheader, .exampleblock > .content h3.subheader, .exampleblock > .content .subheader#toctitle, .sidebarblock.exampleblock > .content > .subheader.title, .exampleblock > .content h4.subheader, .exampleblock > .content h5.subheader, .exampleblock > .content h6.subheader { line-height: 1.4; }
|
||||
.exampleblock.result > .content { -webkit-box-shadow: 0 1px 8px #d9d9d9; box-shadow: 0 1px 8px #d9d9d9; }
|
||||
.sidebarblock { border-style: solid; border-width: 1px; border-color: #d9d9d9; margin-bottom: 1.25em; padding: 1.25em; background: #f2f2f2; -webkit-border-radius: 4px; border-radius: 4px; }
|
||||
.sidebarblock > :first-child { margin-top: 0; }
|
||||
.sidebarblock > :last-child { margin-bottom: 0; }
|
||||
.sidebarblock h1, .sidebarblock h2, .sidebarblock h3, .sidebarblock #toctitle, .sidebarblock > .content > .title, .sidebarblock h4, .sidebarblock h5, .sidebarblock h6, .sidebarblock p { color: #333333; }
|
||||
.sidebarblock h1, .sidebarblock h2, .sidebarblock h3, .sidebarblock #toctitle, .sidebarblock > .content > .title, .sidebarblock h4, .sidebarblock h5, .sidebarblock h6 { line-height: 1; margin-bottom: 0.625em; }
|
||||
.sidebarblock h1.subheader, .sidebarblock h2.subheader, .sidebarblock h3.subheader, .sidebarblock .subheader#toctitle, .sidebarblock > .content > .subheader.title, .sidebarblock h4.subheader, .sidebarblock h5.subheader, .sidebarblock h6.subheader { line-height: 1.4; }
|
||||
.sidebarblock > .content > .title { color: #7a2518; margin-top: 0; line-height: 1.6; }
|
||||
.exampleblock > .content > :last-child > :last-child, .exampleblock > .content .olist > ol > li:last-child > :last-child, .exampleblock > .content .ulist > ul > li:last-child > :last-child, .exampleblock > .content .qlist > ol > li:last-child > :last-child, .sidebarblock > .content > :last-child > :last-child, .sidebarblock > .content .olist > ol > li:last-child > :last-child, .sidebarblock > .content .ulist > ul > li:last-child > :last-child, .sidebarblock > .content .qlist > ol > li:last-child > :last-child { margin-bottom: 0; }
|
||||
.literalblock > .content pre, .listingblock > .content pre { background: none; border-width: 1px 0; border-style: dotted; border-color: #bfbfbf; -webkit-border-radius: 4px; border-radius: 4px; padding: 0.75em 0.75em 0.5em 0.75em; word-wrap: break-word; }
|
||||
.literalblock > .content pre.nowrap, .listingblock > .content pre.nowrap { overflow-x: auto; white-space: pre; word-wrap: normal; }
|
||||
.literalblock > .content pre > code, .listingblock > .content pre > code { display: block; }
|
||||
@media only screen { .literalblock > .content pre, .listingblock > .content pre { font-size: 0.8em; } }
|
||||
@media only screen and (min-width: 768px) { .literalblock > .content pre, .listingblock > .content pre { font-size: 0.9em; } }
|
||||
@media only screen and (min-width: 1280px) { .literalblock > .content pre, .listingblock > .content pre { font-size: 1em; } }
|
||||
.listingblock > .content { position: relative; }
|
||||
.listingblock:hover code[class*=" language-"]:before { text-transform: uppercase; font-size: 0.9em; color: #999; position: absolute; top: 0.375em; right: 0.375em; }
|
||||
.listingblock:hover code.asciidoc:before { content: "asciidoc"; }
|
||||
.listingblock:hover code.clojure:before { content: "clojure"; }
|
||||
.listingblock:hover code.css:before { content: "css"; }
|
||||
.listingblock:hover code.groovy:before { content: "groovy"; }
|
||||
.listingblock:hover code.html:before { content: "html"; }
|
||||
.listingblock:hover code.java:before { content: "java"; }
|
||||
.listingblock:hover code.javascript:before { content: "javascript"; }
|
||||
.listingblock:hover code.python:before { content: "python"; }
|
||||
.listingblock:hover code.ruby:before { content: "ruby"; }
|
||||
.listingblock:hover code.scss:before { content: "scss"; }
|
||||
.listingblock:hover code.xml:before { content: "xml"; }
|
||||
.listingblock:hover code.yaml:before { content: "yaml"; }
|
||||
.listingblock.terminal pre .command:before { content: attr(data-prompt); padding-right: 0.5em; color: #999; }
|
||||
.listingblock.terminal pre .command:not([data-prompt]):before { content: '$'; }
|
||||
table.pyhltable { border: 0; margin-bottom: 0; }
|
||||
table.pyhltable td { vertical-align: top; padding-top: 0; padding-bottom: 0; }
|
||||
table.pyhltable td.code { padding-left: .75em; padding-right: 0; }
|
||||
.highlight.pygments .lineno, table.pyhltable td:not(.code) { color: #999; padding-left: 0; padding-right: .5em; border-right: 1px solid #dddddd; }
|
||||
.highlight.pygments .lineno { display: inline-block; margin-right: .25em; }
|
||||
table.pyhltable .linenodiv { background-color: transparent !important; padding-right: 0 !important; }
|
||||
.quoteblock { margin: 0 0 1.25em; padding: 0.5625em 1.25em 0 1.1875em; border-left: 1px solid #dddddd; }
|
||||
.quoteblock blockquote { margin: 0 0 1.25em 0; padding: 0 0 0.5625em 0; border: 0; }
|
||||
.quoteblock blockquote > .paragraph:last-child p { margin-bottom: 0; }
|
||||
.quoteblock .attribution { margin-top: -.25em; padding-bottom: 0.5625em; font-size: inherit; color: #555555; }
|
||||
.quoteblock .attribution br { display: none; }
|
||||
.quoteblock .attribution cite { display: block; margin-bottom: 0.625em; }
|
||||
table thead th, table tfoot th { font-weight: bold; }
|
||||
table.tableblock.grid-all { border-collapse: separate; border-spacing: 1px; -webkit-border-radius: 4px; border-radius: 4px; border-top: 1px solid #dddddd; border-bottom: 1px solid #dddddd; }
|
||||
table.tableblock.frame-topbot, table.tableblock.frame-none { border-left: 0; border-right: 0; }
|
||||
table.tableblock.frame-sides, table.tableblock.frame-none { border-top: 0; border-bottom: 0; }
|
||||
table.tableblock td .paragraph:last-child p, table.tableblock td > p:last-child { margin-bottom: 0; }
|
||||
th.tableblock.halign-left, td.tableblock.halign-left { text-align: left; }
|
||||
th.tableblock.halign-right, td.tableblock.halign-right { text-align: right; }
|
||||
th.tableblock.halign-center, td.tableblock.halign-center { text-align: center; }
|
||||
th.tableblock.valign-top, td.tableblock.valign-top { vertical-align: top; }
|
||||
th.tableblock.valign-bottom, td.tableblock.valign-bottom { vertical-align: bottom; }
|
||||
th.tableblock.valign-middle, td.tableblock.valign-middle { vertical-align: middle; }
|
||||
p.tableblock.header { color: #222222; font-weight: bold; }
|
||||
td > div.verse { white-space: pre; }
|
||||
ol { margin-left: 1.75em; }
|
||||
ul li ol { margin-left: 1.5em; }
|
||||
dl dd { margin-left: 1.125em; }
|
||||
dl dd:last-child, dl dd:last-child > :last-child { margin-bottom: 0; }
|
||||
ol > li p, ul > li p, ul dd, ol dd, .olist .olist, .ulist .ulist, .ulist .olist, .olist .ulist { margin-bottom: 0.625em; }
|
||||
ul.unstyled, ol.unnumbered, ul.checklist, ul.none { list-style-type: none; }
|
||||
ul.unstyled, ol.unnumbered, ul.checklist { margin-left: 0.625em; }
|
||||
ul.checklist li > p:first-child > i[class^="icon-check"]:first-child, ul.checklist li > p:first-child > input[type="checkbox"]:first-child { margin-right: 0.25em; }
|
||||
ul.checklist li > p:first-child > input[type="checkbox"]:first-child { position: relative; top: 1px; }
|
||||
ul.inline { margin: 0 auto 0.625em auto; margin-left: -1.375em; margin-right: 0; padding: 0; list-style: none; overflow: hidden; }
|
||||
ul.inline > li { list-style: none; float: left; margin-left: 1.375em; display: block; }
|
||||
ul.inline > li > * { display: block; }
|
||||
.unstyled dl dt { font-weight: normal; font-style: normal; }
|
||||
ol.arabic { list-style-type: decimal; }
|
||||
ol.decimal { list-style-type: decimal-leading-zero; }
|
||||
ol.loweralpha { list-style-type: lower-alpha; }
|
||||
ol.upperalpha { list-style-type: upper-alpha; }
|
||||
ol.lowerroman { list-style-type: lower-roman; }
|
||||
ol.upperroman { list-style-type: upper-roman; }
|
||||
ol.lowergreek { list-style-type: lower-greek; }
|
||||
.hdlist > table, .colist > table { border: 0; background: none; }
|
||||
.hdlist > table > tbody > tr, .colist > table > tbody > tr { background: none; }
|
||||
td.hdlist1 { padding-right: .8em; font-weight: bold; }
|
||||
td.hdlist1, td.hdlist2 { vertical-align: top; }
|
||||
.literalblock + .colist, .listingblock + .colist { margin-top: -0.5em; }
|
||||
.colist > table tr > td:first-of-type { padding: 0 .8em; line-height: 1; }
|
||||
.colist > table tr > td:last-of-type { padding: 0.25em 0; }
|
||||
.qanda > ol > li > p > em:only-child { color: #00467f; }
|
||||
.thumb, .th { line-height: 0; display: inline-block; border: solid 4px white; -webkit-box-shadow: 0 0 0 1px #dddddd; box-shadow: 0 0 0 1px #dddddd; }
|
||||
.imageblock.left, .imageblock[style*="float: left"] { margin: 0.25em 0.625em 1.25em 0; }
|
||||
.imageblock.right, .imageblock[style*="float: right"] { margin: 0.25em 0 1.25em 0.625em; }
|
||||
.imageblock > .title { margin-bottom: 0; }
|
||||
.imageblock.thumb, .imageblock.th { border-width: 6px; }
|
||||
.imageblock.thumb > .title, .imageblock.th > .title { padding: 0 0.125em; }
|
||||
.image.left, .image.right { margin-top: 0.25em; margin-bottom: 0.25em; display: inline-block; line-height: 0; }
|
||||
.image.left { margin-right: 0.625em; }
|
||||
.image.right { margin-left: 0.625em; }
|
||||
a.image { text-decoration: none; }
|
||||
span.footnote, span.footnoteref { vertical-align: super; font-size: 0.875em; }
|
||||
span.footnote a, span.footnoteref a { text-decoration: none; }
|
||||
#footnotes { padding-top: 0.75em; padding-bottom: 0.75em; margin-bottom: 0.625em; }
|
||||
#footnotes hr { width: 20%; min-width: 6.25em; margin: -.25em 0 .75em 0; border-width: 1px 0 0 0; }
|
||||
#footnotes .footnote { padding: 0 0.375em; line-height: 1.3; font-size: 0.875em; margin-left: 1.2em; text-indent: -1.2em; margin-bottom: .2em; }
|
||||
#footnotes .footnote a:first-of-type { font-weight: bold; text-decoration: none; }
|
||||
#footnotes .footnote:last-of-type { margin-bottom: 0; }
|
||||
#content #footnotes { margin-top: -0.625em; margin-bottom: 0; padding: 0.75em 0; }
|
||||
.gist .file-data > table { border: none; background: #fff; width: 100%; margin-bottom: 0; }
|
||||
.gist .file-data > table td.line-data { width: 99%; }
|
||||
div.unbreakable { page-break-inside: avoid; }
|
||||
.big { font-size: larger; }
|
||||
.small { font-size: smaller; }
|
||||
.underline { text-decoration: underline; }
|
||||
.overline { text-decoration: overline; }
|
||||
.line-through { text-decoration: line-through; }
|
||||
.aqua { color: #00bfbf; }
|
||||
.aqua-background { background-color: #00fafa; }
|
||||
.black { color: black; }
|
||||
.black-background { background-color: black; }
|
||||
.blue { color: #0000bf; }
|
||||
.blue-background { background-color: #0000fa; }
|
||||
.fuchsia { color: #bf00bf; }
|
||||
.fuchsia-background { background-color: #fa00fa; }
|
||||
.gray { color: #606060; }
|
||||
.gray-background { background-color: #7d7d7d; }
|
||||
.green { color: #006000; }
|
||||
.green-background { background-color: #007d00; }
|
||||
.lime { color: #00bf00; }
|
||||
.lime-background { background-color: #00fa00; }
|
||||
.maroon { color: #600000; }
|
||||
.maroon-background { background-color: #7d0000; }
|
||||
.navy { color: #000060; }
|
||||
.navy-background { background-color: #00007d; }
|
||||
.olive { color: #606000; }
|
||||
.olive-background { background-color: #7d7d00; }
|
||||
.purple { color: #600060; }
|
||||
.purple-background { background-color: #7d007d; }
|
||||
.red { color: #bf0000; }
|
||||
.red-background { background-color: #fa0000; }
|
||||
.silver { color: #909090; }
|
||||
.silver-background { background-color: #bcbcbc; }
|
||||
.teal { color: #006060; }
|
||||
.teal-background { background-color: #007d7d; }
|
||||
.white { color: #bfbfbf; }
|
||||
.white-background { background-color: #fafafa; }
|
||||
.yellow { color: #bfbf00; }
|
||||
.yellow-background { background-color: #fafa00; }
|
||||
span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
|
||||
.admonitionblock td.icon [class^="icon-"]:before { font-size: 2.5em; text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); cursor: default; }
|
||||
.admonitionblock td.icon .icon-note:before { content: "\f05a"; color: #005498; color: #003f72; }
|
||||
.admonitionblock td.icon .icon-tip:before { content: "\f0eb"; text-shadow: 1px 1px 2px rgba(155, 155, 0, 0.8); color: #111; }
|
||||
.admonitionblock td.icon .icon-warning:before { content: "\f071"; color: #bf6900; }
|
||||
.admonitionblock td.icon .icon-caution:before { content: "\f06d"; color: #bf3400; }
|
||||
.admonitionblock td.icon .icon-important:before { content: "\f06a"; color: #bf0000; }
|
||||
.conum { display: inline-block; color: white !important; background-color: #222222; -webkit-border-radius: 100px; border-radius: 100px; text-align: center; width: 20px; height: 20px; font-size: 12px; font-weight: bold; line-height: 20px; font-family: Arial, sans-serif; font-style: normal; position: relative; top: -2px; letter-spacing: -1px; }
|
||||
.conum * { color: white !important; }
|
||||
.conum + b { display: none; }
|
||||
.conum:after { content: attr(data-value); }
|
||||
.conum:not([data-value]):empty { display: none; }
|
||||
.literalblock > .content > pre, .listingblock > .content > pre { -webkit-border-radius: 0; border-radius: 0; }
|
||||
|
||||
/** Spring IO customizations **/
|
||||
|
||||
h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { color: #060; }
|
||||
.subheader, #content #toctitle, .admonitionblock td.content > .title, .exampleblock > .title, .imageblock > .title, .videoblock > .title, .listingblock > .title, .literalblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, .sidebarblock > .title, .tableblock > .title, .verseblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title, .tableblock > caption { color: #080; }
|
Loading…
x
Reference in New Issue
Block a user