tinkerpop-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ok...@apache.org
Subject svn commit: r1740164 - in /incubator/tinkerpop/site/docs/3.1.3-SNAPSHOT/tutorials/gremlin-language-variants: ./ index.html
Date Wed, 20 Apr 2016 16:05:05 GMT
Author: okram
Date: Wed Apr 20 16:05:05 2016
New Revision: 1740164

URL: http://svn.apache.org/viewvc?rev=1740164&view=rev
Log:
added gremlin-language-veriants tutorial build for demo to Ketrina for graphic.

Added:
    incubator/tinkerpop/site/docs/3.1.3-SNAPSHOT/tutorials/gremlin-language-variants/
    incubator/tinkerpop/site/docs/3.1.3-SNAPSHOT/tutorials/gremlin-language-variants/index.html

Added: incubator/tinkerpop/site/docs/3.1.3-SNAPSHOT/tutorials/gremlin-language-variants/index.html
URL: http://svn.apache.org/viewvc/incubator/tinkerpop/site/docs/3.1.3-SNAPSHOT/tutorials/gremlin-language-variants/index.html?rev=1740164&view=auto
==============================================================================
--- incubator/tinkerpop/site/docs/3.1.3-SNAPSHOT/tutorials/gremlin-language-variants/index.html (added)
+++ incubator/tinkerpop/site/docs/3.1.3-SNAPSHOT/tutorials/gremlin-language-variants/index.html Wed Apr 20 16:05:05 2016
@@ -0,0 +1,1318 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="generator" content="Asciidoctor 0.1.4">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Gremlin Language Variants</title>
+<style>
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*! normalize.css v2.1.2 | MIT License | git.io/normalize */
+/* ========================================================================== HTML5 display definitions ========================================================================== */
+/** Correct `block` display not defined in IE 8/9. */
+@import url(http://cdnjs.cloudflare.com/ajax/libs/font-awesome/3.2.1/css/font-awesome.css);
+article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary { display: block; }
+
+/** Correct `inline-block` display not defined in IE 8/9. */
+audio, canvas, video { display: inline-block; }
+
+/** Prevent modern browsers from displaying `audio` without controls. Remove excess height in iOS 5 devices. */
+audio:not([controls]) { display: none; height: 0; }
+
+/** Address `[hidden]` styling not present in IE 8/9. Hide the `template` element in IE, Safari, and Firefox < 22. */
+[hidden], template { display: none; }
+
+script { display: none !important; }
+
+/* ========================================================================== Base ========================================================================== */
+/** 1. Set default font family to sans-serif. 2. Prevent iOS text size adjust after orientation change, without disabling user zoom. */
+html { font-family: sans-serif; /* 1 */ -ms-text-size-adjust: 100%; /* 2 */ -webkit-text-size-adjust: 100%; /* 2 */ }
+
+/** Remove default margin. */
+body { margin: 0; }
+
+/* ========================================================================== Links ========================================================================== */
+/** Remove the gray background color from active links in IE 10. */
+a { background: transparent; }
+
+/** Address `outline` inconsistency between Chrome and other browsers. */
+a:focus { outline: thin dotted; }
+
+/** Improve readability when focused and also mouse hovered in all browsers. */
+a:active, a:hover { outline: 0; }
+
+/* ========================================================================== Typography ========================================================================== */
+/** Address variable `h1` font-size and margin within `section` and `article` contexts in Firefox 4+, Safari 5, and Chrome. */
+h1 { font-size: 2em; margin: 0.67em 0; }
+
+/** Address styling not present in IE 8/9, Safari 5, and Chrome. */
+abbr[title] { border-bottom: 1px dotted; }
+
+/** Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome. */
+b, strong { font-weight: bold; }
+
+/** Address styling not present in Safari 5 and Chrome. */
+dfn { font-style: italic; }
+
+/** Address differences between Firefox and other browsers. */
+hr { -moz-box-sizing: content-box; box-sizing: content-box; height: 0; }
+
+/** Address styling not present in IE 8/9. */
+mark { background: #ff0; color: #000; }
+
+/** Correct font family set oddly in Safari 5 and Chrome. */
+code, kbd, pre, samp { font-family: monospace, serif; font-size: 1em; }
+
+/** Improve readability of pre-formatted text in all browsers. */
+pre { white-space: pre-wrap; }
+
+/** Set consistent quote types. */
+q { quotes: "\201C" "\201D" "\2018" "\2019"; }
+
+/** Address inconsistent and variable font size in all browsers. */
+small { font-size: 80%; }
+
+/** Prevent `sub` and `sup` affecting `line-height` in all browsers. */
+sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
+
+sup { top: -0.5em; }
+
+sub { bottom: -0.25em; }
+
+/* ========================================================================== Embedded content ========================================================================== */
+/** Remove border when inside `a` element in IE 8/9. */
+img { border: 0; }
+
+/** Correct overflow displayed oddly in IE 9. */
+svg:not(:root) { overflow: hidden; }
+
+/* ========================================================================== Figures ========================================================================== */
+/** Address margin not present in IE 8/9 and Safari 5. */
+figure { margin: 0; }
+
+/* ========================================================================== Forms ========================================================================== */
+/** Define consistent border, margin, and padding. */
+fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; }
+
+/** 1. Correct `color` not being inherited in IE 8/9. 2. Remove padding so people aren't caught out if they zero out fieldsets. */
+legend { border: 0; /* 1 */ padding: 0; /* 2 */ }
+
+/** 1. Correct font family not being inherited in all browsers. 2. Correct font size not being inherited in all browsers. 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome. */
+button, input, select, textarea { font-family: inherit; /* 1 */ font-size: 100%; /* 2 */ margin: 0; /* 3 */ }
+
+/** Address Firefox 4+ setting `line-height` on `input` using `!important` in the UA stylesheet. */
+button, input { line-height: normal; }
+
+/** Address inconsistent `text-transform` inheritance for `button` and `select`. All other form control elements do not inherit `text-transform` values. Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+. Correct `select` style inheritance in Firefox 4+ and Opera. */
+button, select { text-transform: none; }
+
+/** 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` and `video` controls. 2. Correct inability to style clickable `input` types in iOS. 3. Improve usability and consistency of cursor style between image-type `input` and others. */
+button, html input[type="button"], input[type="reset"], input[type="submit"] { -webkit-appearance: button; /* 2 */ cursor: pointer; /* 3 */ }
+
+/** Re-set default cursor for disabled elements. */
+button[disabled], html input[disabled] { cursor: default; }
+
+/** 1. Address box sizing set to `content-box` in IE 8/9. 2. Remove excess padding in IE 8/9. */
+input[type="checkbox"], input[type="radio"] { box-sizing: border-box; /* 1 */ padding: 0; /* 2 */ }
+
+/** 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome (include `-moz` to future-proof). */
+input[type="search"] { -webkit-appearance: textfield; /* 1 */ -moz-box-sizing: content-box; -webkit-box-sizing: content-box; /* 2 */ box-sizing: content-box; }
+
+/** Remove inner padding and search cancel button in Safari 5 and Chrome on OS X. */
+input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; }
+
+/** Remove inner padding and border in Firefox 4+. */
+button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; }
+
+/** 1. Remove default vertical scrollbar in IE 8/9. 2. Improve readability and alignment in all browsers. */
+textarea { overflow: auto; /* 1 */ vertical-align: top; /* 2 */ }
+
+/* ========================================================================== Tables ========================================================================== */
+/** Remove most spacing between table cells. */
+table { border-collapse: collapse; border-spacing: 0; }
+
+meta.foundation-mq-small { font-family: "only screen and (min-width: 768px)"; width: 768px; }
+
+meta.foundation-mq-medium { font-family: "only screen and (min-width:1280px)"; width: 1280px; }
+
+meta.foundation-mq-large { font-family: "only screen and (min-width:1440px)"; width: 1440px; }
+
+*, *: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; }
+
+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, .listingblock > .title, .literalblock > .title, .mathblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, .sidebarblock > .title, .tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title, .tableblock > caption { line-height: 1.4; color: #6c818f; font-weight: 300; margin-top: 0.2em; margin-bottom: 0.5em; }
+
+/* Typography resets */
+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; }
+
+/* Default Link Styles */
+a { color: #444444; text-decoration: underline; line-height: inherit; }
+a:hover, a:focus { color: #111111; }
+a img { border: none; }
+
+/* Default paragraph styles */
+p { font-family: inherit; font-weight: normal; font-size: 1em; line-height: 1.5; margin-bottom: 1.25em; text-rendering: optimizeLegibility; }
+p aside { font-size: 0.875em; line-height: 1.35; font-style: italic; }
+
+/* Default header styles */
+h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { font-family: ff-meta-web-pro-1, ff-meta-web-pro-2, Arial, "Helvetica Neue", sans-serif; font-weight: bold; font-style: normal; color: #465158; 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: #909ea7; 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; }
+
+/* Helpful Typography Defaults */
+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", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", monospace; font-weight: normal; color: #444444; }
+
+/* Lists */
+ul, ol, dl { font-size: 1em; line-height: 1.5; margin-bottom: 1.25em; list-style-position: outside; font-family: inherit; }
+
+ul, ol { margin-left: 0; }
+ul.no-bullet, ol.no-bullet { margin-left: 0; }
+
+/* Unordered Lists */
+ul li ul, ul li ol { margin-left: 1.25em; margin-bottom: 0; font-size: 1em; /* Override nested font-size change */ }
+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; }
+
+/* Ordered Lists */
+ol li ul, ol li ol { margin-left: 1.25em; margin-bottom: 0; }
+
+/* Definition Lists */
+dl dt { margin-bottom: 0.3em; font-weight: bold; }
+dl dd { margin-bottom: 0.75em; }
+
+/* Abbreviations */
+abbr, acronym { text-transform: uppercase; font-size: 90%; color: black; border-bottom: 1px dotted #dddddd; cursor: help; }
+
+abbr { text-transform: none; }
+
+/* Blockquotes */
+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: 0.8125em; color: #748590; }
+blockquote cite:before { content: "\2014 \0020"; }
+blockquote cite a, blockquote cite a:visited { color: #748590; }
+
+blockquote, blockquote p { line-height: 1.5; color: #909ea7; }
+
+/* Microformats */
+.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 styles.  Inlined to avoid required HTTP connection: www.phpied.com/delay-loading-your-print-css/ Credit to Paul Irish and HTML5 Boilerplate (html5boilerplate.com)
+*/
+.print-only { display: none !important; }
+
+@media print { * { background: transparent !important; color: #000 !important; /* Black prints faster: h5bp.com/s */ 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; /* h5bp.com/t */ }
+  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; } }
+/* Tables */
+table { background: white; margin-bottom: 1.25em; border: solid 0 #dddddd; }
+table thead, table tfoot { background: none; font-weight: bold; }
+table thead tr th, table thead tr td, table tfoot tr th, table tfoot tr td { padding: 1px 8px 1px 5px; font-size: 1em; color: #222222; text-align: left; }
+table tr th, table tr td { padding: 1px 8px 1px 5px; font-size: 1em; color: #222222; }
+table tr.even, table tr.alt, table tr:nth-of-type(even) { background: none; }
+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.5; }
+
+.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.95em; padding: 0; white-space: nowrap; background-color: #f2f2f2; border: 0 solid #dddddd; -webkit-border-radius: 6px; border-radius: 6px; text-shadow: none; }
+
+pre, pre > code { line-height: 1.2; color: inherit; font-family: "Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", monospace; font-weight: normal; }
+
+.keyseq { color: #333333; }
+
+kbd:not(.keyseq) { display: inline-block; color: black; 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; }
+
+.keyseq kbd:first-child { margin-left: 0; }
+
+.keyseq kbd:last-child { margin-right: 0; }
+
+.menuseq, .menu { color: black; }
+
+b.button:before, b.button:after { position: relative; top: -1px; font-weight: normal; }
+
+b.button:before { content: "["; padding: 0 3px 0 2px; }
+
+b.button:after { content: "]"; padding: 0 2px 0 3px; }
+
+p a > code:hover { color: #373737; }
+
+#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: #111111; font-weight: bold; border-bottom: 1px solid #dddddd; margin-bottom: -28px; padding-bottom: 32px; }
+#header span { color: #909ea7; }
+#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: 1px solid #dddddd; 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: #6c818f; }
+
+@media only screen and (min-width: 768px) { body.toc2 { padding-left: 15em; padding-right: 0; }
+  #toc.toc2 { position: fixed; width: 15em; left: 0; top: 0; border-right: 1px solid #dddddd; border-bottom: 0; z-index: 1000; padding: 1em; height: 100%; overflow: auto; }
+  #toc.toc2 #toctitle { margin-top: 0; font-size: 1.2em; }
+  #toc.toc2 > ul { font-size: .90em; }
+  #toc.toc2 ul ul { margin-left: 0; padding-left: 1em; }
+  #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: 15em; }
+  body.toc2.toc-right #toc.toc2 { border-right: 0; border-left: 1px solid #dddddd; left: auto; right: 0; } }
+@media only screen and (min-width: 1280px) { body.toc2 { padding-left: 20em; padding-right: 0; }
+  #toc.toc2 { width: 20em; }
+  #toc.toc2 #toctitle { font-size: 1.375em; }
+  #toc.toc2 > ul { font-size: 0.95em; }
+  #toc.toc2 ul ul { padding-left: 1.25em; }
+  body.toc2.toc-right { padding-left: 0; padding-right: 20em; } }
+#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: 6px; border-radius: 6px; }
+#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: ff-meta-web-pro-1, ff-meta-web-pro-2, Arial, "Helvetica Neue", sans-serif; font-size: 1em; padding-left: 0.125em; }
+
+#footer { max-width: 100%; background-color: black; padding: 1.25em; }
+
+#footer-text { color: white; line-height: 1.35; }
+
+.sect1 { padding-bottom: 1.25em; }
+
+.sect1 + .sect1 { border-top: 1px solid #dddddd; }
+
+#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: #465158; 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: #3b444a; }
+
+.imageblock, .literalblock, .listingblock, .mathblock, .verseblock, .videoblock { margin-bottom: 1.25em; }
+
+.admonitionblock td.content > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .mathblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, .sidebarblock > .title, .tableblock > .title, .verseblock > .title, .videoblock > .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: #909ea7; }
+.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: 6px; border-radius: 6px; }
+.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: 6px; border-radius: 6px; }
+.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: #6c818f; margin-top: 0; line-height: 1.5; }
+
+.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 pre:not([class]), .listingblock pre:not([class]) { background: #eeeeee; }
+.literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { border-width: 1px; border-style: solid; border-color: #cccccc; -webkit-border-radius: 6px; border-radius: 6px; padding: 0.5em; word-wrap: break-word; }
+.literalblock pre.nowrap, .literalblock pre[class].nowrap, .listingblock pre.nowrap, .listingblock pre[class].nowrap { overflow-x: auto; white-space: pre; word-wrap: normal; }
+.literalblock pre > code, .literalblock pre[class] > code, .listingblock pre > code, .listingblock pre[class] > code { display: block; }
+@media only screen { .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { font-size: 0.76em; } }
+@media only screen and (min-width: 768px) { .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { font-size: 0.855em; } }
+@media only screen and (min-width: 1280px) { .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { font-size: 0.95em; } }
+
+.listingblock pre.highlight { padding: 0; }
+.listingblock pre.highlight > code { padding: 0.5em; }
+
+.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.sass:before { content: "sass"; }
+.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: 0.8125em; color: #748590; }
+.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: 6px; border-radius: 6px; border-top: 0 solid #dddddd; border-bottom: 0 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 > p:last-child, table.tableblock th > p:last-child, 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; }
+
+tbody tr th { display: table-cell; line-height: 1.5; background: none; }
+
+tbody tr th, tbody tr th p, tfoot tr th, tfoot tr th p { color: #222222; font-weight: bold; }
+
+td > div.verse { white-space: pre; }
+
+ol { margin-left: 0.25em; }
+
+ul li ol { margin-left: 0; }
+
+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: .75em; 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 .75em; line-height: 1; }
+.colist > table tr > td:last-of-type { padding: 0.25em 0; }
+
+.qanda > ol > li > p > em:only-child { color: #373737; }
+
+.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: #444444; color: #333333; }
+.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: black; -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; }
+
+.listingblock code { white-space: pre; overflow: auto; overflow-wrap: normal; /* needed for webkit browsers */ }
+
+#toc ul.sectlevel0 > li > a { font-style: normal; font-weight: bold; }
+
+h4 { color: #6c818f; }
+
+.literalblock > .content > pre, .listingblock > .content > pre { -webkit-border-radius: 6px; border-radius: 6px; margin-left: 2em; margin-right: 2em; }
+
+.admonitionblock { margin-left: 2em; margin-right: 2em; }
+.admonitionblock > table { border: 1px solid #609060; border-top-width: 1.5em; background-color: #e9ffe9; border-collapse: separate; -webkit-border-radius: 0; border-radius: 0; }
+.admonitionblock > table td.icon { padding-top: .5em; padding-bottom: .5em; }
+.admonitionblock > table td.content { padding: .5em 1em; color: black; font-size: .9em; border-left: none; }
+
+.sidebarblock { background-color: #e8ecef; border-color: #ccc; }
+.sidebarblock > .content > .title { color: #444444; }
+
+table.tableblock.grid-all { border-collapse: collapse; -webkit-border-radius: 0; border-radius: 0; }
+table.tableblock.grid-all th.tableblock, table.tableblock.grid-all td.tableblock { border-bottom: 1px solid #aaa; }
+
+#footer { background-color: #465158; padding: 2em; }
+
+#footer-text { color: #eee; font-size: 0.8em; text-align: center; }
+</style>
+<style>
+/* Foundation stylesheet for CodeRay (to match GitHub theme) | MIT License | http://foundation.zurb.com */
+table.CodeRay { border-collapse: collapse; padding: 2px; margin-bottom: 0; border: 0; background: transparent; }
+table.CodeRay td { padding: 0 .5em; vertical-align: top; }
+table.CodeRay td.line-numbers { text-align: right; color: #999; border-right: 1px solid #e5e5e5; padding-left: 0; }
+span.line-numbers { border-right: 1px solid #E5E5E5; color: #999; display: inline-block; margin-right: 0.5em; padding-right: 0.5em; }
+.CodeRay td.line-numbers strong, .CodeRay span.line-numbers strong { font-weight: normal; }
+.CodeRay .debug { color: white !important; background: blue !important; }
+.CodeRay .annotation { color: #007; }
+.CodeRay .attribute-name { color: #f08; }
+.CodeRay .attribute-value { color: #700; }
+.CodeRay .binary { color: #509; }
+.CodeRay .comment  { color: #999; font-style: italic; }
+.CodeRay .char { color: #04D; }
+.CodeRay .char .content { color: #04D; }
+.CodeRay .char .delimiter { color: #039; }
+.CodeRay .class { color: #458; }
+.CodeRay .complex { color: #A08; }
+.CodeRay .constant { color: teal; }
+.CodeRay .color { color: #0A0; }
+.CodeRay .class-variable { color: #369; }
+.CodeRay .decorator { color: #B0B; }
+.CodeRay .definition { color: #099; }
+.CodeRay .directive { color: #088; }
+.CodeRay .delimiter { color: black; }
+.CodeRay .doc { color: #970; }
+.CodeRay .doctype { color: #34b; }
+.CodeRay .doc-string { color: #D42; }
+.CodeRay .escape  { color: #666; }
+.CodeRay .entity { color: #800; }
+.CodeRay .error { color: #808; }
+.CodeRay .exception { color: #C00; }
+.CodeRay .filename { color: #099; }
+.CodeRay .function { color: #900; }
+.CodeRay .global-variable { color: teal; }
+.CodeRay .hex { color: #058; }
+.CodeRay .integer  { color: #099; }
+.CodeRay .include { color: #B44; }
+.CodeRay .inline { color: black; }
+.CodeRay .inline .inline { background: #ccc; }
+.CodeRay .inline .inline .inline { background: #bbb; }
+.CodeRay .inline .inline-delimiter { color: #D14; }
+.CodeRay .inline-delimiter { color: #D14; }
+.CodeRay .important { color: #f00; }
+.CodeRay .interpreted { color: #B2B; }
+.CodeRay .instance-variable { color: teal; }
+.CodeRay .label { color: #970; }
+.CodeRay .local-variable { color: #963; }
+.CodeRay .octal { color: #40E; }
+.CodeRay .predefined { color: #369; }
+.CodeRay .preprocessor { color: #579; }
+.CodeRay .pseudo-class { color: #00C; }
+.CodeRay .predefined-type { color: #074; }
+.CodeRay .reserved, .keyword  { color: #000; }
+.CodeRay .key { color: #808; }
+.CodeRay .key .delimiter { color: #606; }
+.CodeRay .key .char { color: #80f; }
+.CodeRay .value { color: #088; }
+.CodeRay .regexp { background-color: #fff0ff; }
+.CodeRay .regexp .content { color: #808; }
+.CodeRay .regexp .delimiter { color: #404; }
+.CodeRay .regexp .modifier { color: #C2C; }
+.CodeRay .regexp .function  { color: #404; font-weight: bold; }
+.CodeRay .string { color: #D20; }
+.CodeRay .string .string { }
+.CodeRay .string .string .string { background-color: #ffd0d0; }
+.CodeRay .string .content { color: #D14; }
+.CodeRay .string .char { color: #D14; }
+.CodeRay .string .delimiter { color: #D14; }
+.CodeRay .shell { color: #D14; }
+.CodeRay .shell .content { }
+.CodeRay .shell .delimiter { color: #D14; }
+.CodeRay .symbol { color: #990073; }
+.CodeRay .symbol .content { color: #A60; }
+.CodeRay .symbol .delimiter { color: #630; }
+.CodeRay .tag, .CodeRay .attribute-name { color: #070; }
+.CodeRay .tag-special { color: #D70; }
+.CodeRay .type { color: #339; }
+.CodeRay .variable  { color: #036; }
+.CodeRay .insert { background: #afa; }
+.CodeRay .delete { background: #faa; }
+.CodeRay .change { color: #aaf; background: #007; }
+.CodeRay .head { color: #f8f; background: #505; }
+.CodeRay .insert .insert { color: #080; }
+.CodeRay .delete .delete { color: #800; }
+.CodeRay .change .change { color: #66f; }
+.CodeRay .head .head { color: #f4f; }
+
+</style>
+</head>
+<body class="article">
+<div id="header">
+</div>
+<div id="content">
+<div class="imageblock">
+<div class="content">
+<img src="../../images/apache-tinkerpop-logo.png" alt="apache tinkerpop logo" width="500">
+</div>
+</div>
+<div class="sect1">
+<h2 id="_gremlin_language_variants">Gremlin Language Variants</h2>
+<div class="sectionbody">
+<div class="paragraph">
+<p>Gremlin is an embeddable query language able to represent itself within the constructs of existing programming languages.
+Any programming language that supports function composition (e.g. fluent chaining) and function nesting (e.g. call stacks)
+can support Gremlin. With Gremlin, the distinction between a programming language and a query language is not be as
+strongly divided as they have historically been. For instance, with Gremlin-Java, the developer is able to have their
+application code and their graph database queries at the same level of abstraction. A simple example is presented below
+where the <code>MyApplication</code> Java class contains both application-level and database-level code all within the constructs
+of Java.</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay"><code class="java language-java"><span class="directive">public</span> <span class="type">class</span> <span class="class">MyApplication</span> {
+
+  <span class="directive">public</span> <span class="directive">static</span> <span class="type">void</span> run(<span class="directive">final</span> <span class="predefined-type">String</span><span class="type">[]</span> args) {
+    <span class="comment">// assumes args[0] is a configuration file location</span>
+    Graph graph = GraphFactory.open(args[<span class="integer">0</span>]);
+    GraphTraversalSource g = graph.traversal();
+
+    <span class="comment">// assumes that args[1] is a vertex id</span>
+    <span class="type">double</span> averageRating =
+      g.V(args[<span class="integer">1</span>]).out(<span class="string"><span class="delimiter">&quot;</span><span class="content">created</span><span class="delimiter">&quot;</span></span>).inE(<span class="string"><span class="delimiter">&quot;</span><span class="content">rated</span><span class="delimiter">&quot;</span></span>).
+        values(<span class="string"><span class="delimiter">&quot;</span><span class="content">stars</span><span class="delimiter">&quot;</span></span>).mean().next();
+
+    <span class="predefined-type">String</span> personName = g.V(args[<span class="integer">1</span>]).values(<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>).next();
+
+    <span class="predefined-type">System</span>.out.println(<span class="string"><span class="delimiter">&quot;</span><span class="content">Average rating of </span><span class="delimiter">&quot;</span></span> + personName + <span class="string"><span class="delimiter">&quot;</span><span class="content"> projects is: </span><span class="delimiter">&quot;</span></span> + averageRating);
+  }
+
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>In query languages like <a href="https://en.wikipedia.org/wiki/SQL">SQL</a>, the user must construct a string representation of
+their query and submit it to the database for evaluation. The same example above is presented below in Java using SQL and the
+<a href="https://en.wikipedia.org/wiki/Java_Database_Connectivity">JDBC</a> interface.</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay"><code class="java language-java"><span class="directive">public</span> <span class="type">class</span> <span class="class">MyApplication</span> {
+
+  <span class="directive">public</span> <span class="directive">static</span> <span class="type">void</span> run(<span class="directive">final</span> <span class="predefined-type">String</span><span class="type">[]</span> args) {
+    <span class="comment">// assumes args[0] is a URI to the database</span>
+    <span class="predefined-type">Connection</span> connection = <span class="predefined-type">DriverManager</span>.getConnection(args[<span class="integer">0</span>])
+    <span class="predefined-type">Statement</span> statement = connection.createStatement();
+
+    <span class="comment">// assumes that args[1] is a vertex id</span>
+    <span class="predefined-type">ResultSet</span> result = statement.executeQuery(
+      <span class="string"><span class="delimiter">&quot;</span><span class="content">SELECT p.name as NAME, AVG(c.stars) as AVERAGE FROM PERSONS p</span><span class="delimiter">&quot;</span></span> +
+        <span class="string"><span class="delimiter">&quot;</span><span class="content">INNER JOIN CREATED c ON c.person = p.id </span><span class="delimiter">&quot;</span></span> +
+        <span class="string"><span class="delimiter">&quot;</span><span class="content">WHERE p.id = '</span><span class="delimiter">&quot;</span></span> + args[<span class="integer">1</span>] + <span class="string"><span class="delimiter">&quot;</span><span class="content">'</span><span class="delimiter">&quot;</span></span>);
+
+    result.next();
+    <span class="type">double</span> averageRating = result.getDouble(<span class="string"><span class="delimiter">&quot;</span><span class="content">AVERAGE</span><span class="delimiter">&quot;</span></span>);
+    <span class="predefined-type">String</span> personName = result.getString(<span class="string"><span class="delimiter">&quot;</span><span class="content">NAME</span><span class="delimiter">&quot;</span></span>);
+
+    <span class="predefined-type">System</span>.out.println(<span class="string"><span class="delimiter">&quot;</span><span class="content">Average rating of </span><span class="delimiter">&quot;</span></span> + personName + <span class="string"><span class="delimiter">&quot;</span><span class="content"> projects is: </span><span class="delimiter">&quot;</span></span> + averageRating);
+  }
+
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The purpose of this tutorial is to explain how to develop a Gremlin language variant. That is, for those developers that
+are interested in supporting Gremlin in their native language and there currently does not exist a (good) Gremlin variant for
+their language, can develop one for both their language community and the Apache TinkerPop community to use. For this
+tutorial, Python will be used and three different design models are presented. Any variant will use one of the models
+below.</p>
+</div>
+<div class="olist arabic">
+<ol class="arabic">
+<li>
+<p><a href="#using-jython-and-the-jvm"><strong>Using Jython and the JVM</strong></a>: This is perhaps the easiest way to produce a Gremlin
+language variant. With <a href="https://www.jcp.org/en/jsr/detail?id=223">JSR-223</a>, any language compiler written for the JVM
+can directly access the JVM and any of its libraries (including Gremlin).</p>
+</li>
+<li>
+<p><a href="#using-python-and-jni"><strong>Using Python and JNI</strong></a>: This is similar to the first model save that a non-JVM Python version is used.
+However, the JVM is interacted with using <a href="https://en.wikipedia.org/wiki/Java_Native_Interface">JNI</a> to construct a Gremlin traversal
+for execution on the JVM, but whose result set is converted to Python for the native language developer.</p>
+</li>
+<li>
+<p><a href="#using-python-and-gremlin-server"><strong>Using Python and GremlinServer</strong></a>: This model requires that there exist a Python
+class that mimics Gremlin-Java&#8217;s <code>GraphTraversal</code> API. With each method calls of this Python class, a <code>ScriptEngine</code>
+string is constructed (e.g. Gremlin-Groovy). Ultimately, that constructed traversal (represented behind the
+scenes as a string) is submitted to a Gremlin-Server compliant graph system for evaluation.</p>
+</li>
+</ol>
+</div>
+<div class="admonitionblock important">
+<table>
+<tr>
+<td class="icon">
+<div class="title">Important</div>
+</td>
+<td class="content">
+Gremlin-Java is considered the idiomatic, standard implementation of Gremlin. Any Gremlin language variant,
+regardless of the implementation model chosen, <strong>must</strong>, within the constraints of the host language, be in 1-to-1
+correspondence with Gremlin-Java.
+</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_implementation_requirements">Implementation Requirements</h2>
+<div class="sectionbody">
+<div class="paragraph">
+<p>Every language variant implementation, regardless of the model used above, will have to account for four core concepts below:</p>
+</div>
+<div class="olist arabic">
+<ol class="arabic">
+<li>
+<p><code>Graph</code>: The graph instance that enables the creation of a <code>GraphTraversalSource</code> via <code>graph.traversal()</code>.</p>
+</li>
+<li>
+<p><code>GraphTraversalSource</code>: The class is the typical <code>g</code> instance. It maintain all the <code>withXXX()</code> methods as well as the
+"traversal source"-methods such as <code>V()</code>, <code>E()</code>, <code>addV()</code>, etc.</p>
+</li>
+<li>
+<p><code>GraphTraversal</code>: The primary traversal class that has every traversal step method such as <code>out()</code>, <code>groupCount()</code>,
+<code>match()</code>, etc.</p>
+</li>
+<li>
+<p><code>__</code>: The anonymous traversal class that is used for nested traversals. An example includes <code>repeat(__.out())</code>.</p>
+</li>
+</ol>
+</div>
+<div class="paragraph">
+<p>Historically, many Gremlin language variants have failed to make these distinction clear and in doing so, either
+complicate their implementations or yield variants that are not in 1-to-1 correspondence with Gremlin-Java. Note that most
+variants will only have to consider <code>GraphTraversalSource</code>, <code>GraphTraversal</code>, and <code>__</code>.</p>
+</div>
+<div class="admonitionblock note">
+<table>
+<tr>
+<td class="icon">
+<div class="title">Note</div>
+</td>
+<td class="content">
+<code>GraphTraversal</code> is a particular Gremlin domain-specific language (<a href="https://en.wikipedia.org/wiki/Domain-specific_language">DSL</a>),
+albeit the most popular and foundational DSL. If another DSL is created, then the same techniques discussed for <code>GraphTraversal</code>
+apply to <code>XXXTraversal</code>.
+</td>
+</tr>
+</table>
+</div>
+<div class="admonitionblock important">
+<table>
+<tr>
+<td class="icon">
+<div class="title">Important</div>
+</td>
+<td class="content">
+The term "Gremlin-Java" denotes the language that is defined by <code>GraphTraversalSource</code>, <code>GraphTraversal</code>,
+and <code>__</code>. These three classes exist in <code>org.apache.tinkerpop.gremlin.process.traversal.dsl.graph</code> and form the definitive
+representation of the Gremlin traversal language.
+</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="using-jython-and-the-jvm">Using Jython and the JVM</h2>
+<div class="sectionbody">
+<div class="paragraph">
+<p><a href="http://www.jython.org/">Jython</a> is a <a href="https://www.jcp.org/en/jsr/detail?id=223">JSR-223</a> implementation that allows
+for the evaluation of Python on the <a href="https://en.wikipedia.org/wiki/Java_virtual_machine">Java virtual machine</a>.
+In other words, Jython&#8217;s virtual machine is not the standard <a href="https://wiki.python.org/moin/CPython">CPython</a> reference implementation
+distributed with most operating systems, but instead the JVM. The benefit of Jython is that Python code and classes can interact
+with the Java API and any Java packages on the <code>CLASSPATH</code>. This makes any JSR-224 Gremlin language variant "implementation" trivial.</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay"><code class="python language-python">&gt;&gt;&gt; <span class="keyword">import</span> <span class="include">sys</span>
+<span class="comment"># this list is longer, including all jars in lib/, not just Apache TinkerPop jars</span>
+&gt;&gt;&gt; sys.path.append(<span class="string"><span class="delimiter">&quot;</span><span class="content">/usr/local/apache-gremlin-console-3.1.3-SNAPSHOT-standalone/lib/gremlin-console-3.1.3-SNAPSHOT.jar</span><span class="delimiter">&quot;</span></span>)
+&gt;&gt;&gt; sys.path.append(<span class="string"><span class="delimiter">&quot;</span><span class="content">/usr/local/apache-gremlin-console-3.1.3-SNAPSHOT-standalone/lib/gremlin-core-3.1.3-SNAPSHOT.jar</span><span class="delimiter">&quot;</span></span>)
+&gt;&gt;&gt; sys.path.append(<span class="string"><span class="delimiter">&quot;</span><span class="content">/usr/local/apache-gremlin-console-3.1.3-SNAPSHOT-standalone/lib/gremlin-driver-3.1.3-SNAPSHOT.jar</span><span class="delimiter">&quot;</span></span>)
+&gt;&gt;&gt; sys.path.append(<span class="string"><span class="delimiter">&quot;</span><span class="content">/usr/local/apache-gremlin-console-3.1.3-SNAPSHOT-standalone/lib/gremlin-shaded-3.1.3-SNAPSHOT.jar</span><span class="delimiter">&quot;</span></span>)
+&gt;&gt;&gt; sys.path.append(<span class="string"><span class="delimiter">&quot;</span><span class="content">/usr/local/apache-gremlin-console-3.1.3-SNAPSHOT-standalone/ext/tinkergraph-gremlin/lib/tinkergraph-gremlin-3.1.3-SNAPSHOT.jar</span><span class="delimiter">&quot;</span></span>)
+<span class="comment"># import Java classes</span>
+&gt;&gt;&gt; <span class="keyword">from</span> <span class="include">org.apache.tinkerpop.gremlin.tinkergraph.structure</span> <span class="keyword">import</span> <span class="include">TinkerFactory</span>
+&gt;&gt;&gt; <span class="keyword">from</span> <span class="include">org.apache.tinkerpop.gremlin.process.traversal.dsl.graph</span> <span class="keyword">import</span> <span class="include">__</span>
+<span class="comment"># create a the toy &quot;modern&quot; graph for the example and spawn a GraphTraversalSource</span>
+&gt;&gt;&gt; graph = TinkerFactory.createModern()
+&gt;&gt;&gt; g = graph.traversal()
+<span class="comment"># The Jython shell does not automatically iterate Iterators like the Gremlin Console</span>
+&gt;&gt;&gt; g.V().hasLabel(<span class="string"><span class="delimiter">&quot;</span><span class="content">person</span><span class="delimiter">&quot;</span></span>).out(<span class="string"><span class="delimiter">&quot;</span><span class="content">knows</span><span class="delimiter">&quot;</span></span>).out(<span class="string"><span class="delimiter">&quot;</span><span class="content">created</span><span class="delimiter">&quot;</span></span>)
+[GraphStep(vertex,[]), HasStep([~label.eq(person)]), VertexStep(OUT,[knows],vertex), VertexStep(OUT,[created],vertex)]
+<span class="comment"># toList() will do the iteration and return the results as a list</span>
+&gt;&gt;&gt; g.V().hasLabel(<span class="string"><span class="delimiter">&quot;</span><span class="content">person</span><span class="delimiter">&quot;</span></span>).out(<span class="string"><span class="delimiter">&quot;</span><span class="content">knows</span><span class="delimiter">&quot;</span></span>).out(<span class="string"><span class="delimiter">&quot;</span><span class="content">created</span><span class="delimiter">&quot;</span></span>).toList()
+[v[<span class="integer">5</span>], v[<span class="integer">3</span>]]
+&gt;&gt;&gt; g.V().repeat(__.out()).times(<span class="integer">2</span>).values(<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>).toList()
+[ripple, lop]
+<span class="comment"># results can be interacted with using Python</span>
+&gt;&gt;&gt; g.V().repeat(__.out()).times(<span class="integer">2</span>).values(<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>).toList()[<span class="integer">0</span>]
+<span class="string"><span class="modifier">u</span><span class="delimiter">'</span><span class="content">ripple</span><span class="delimiter">'</span></span>
+&gt;&gt;&gt; g.V().repeat(__.out()).times(<span class="integer">2</span>).values(<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>).toList()[<span class="integer">0</span>][<span class="integer">0</span>:<span class="integer">3</span>].upper()
+<span class="string"><span class="modifier">u</span><span class="delimiter">'</span><span class="content">RIP</span><span class="delimiter">'</span></span>
+&gt;&gt;&gt;</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Most every JSR-223 <code>ScriptEngine</code> language will allow the developer to immediately interact with <code>GraphTraversal</code>.
+The benefit of this model is that nearly every major programming language has a respective <code>ScriptEngine</code>:
+<a href="https://en.wikipedia.org/wiki/Nashorn_(JavaScript_engine)">JavaScript</a>, <a href="http://groovy-lang.org/">Groovy</a>,
+<a href="http://www.scala-lang.org/">Scala</a>, Lisp (<a href="https://clojure.org/">Clojure</a>), <a href="http://jruby.org/">Ruby</a>, etc. A
+list of implementations is provided <a href="https://en.wikipedia.org/wiki/List_of_JVM_languages">here</a>.</p>
+</div>
+<div class="sect2">
+<h3 id="_traversal_wrappers">Traversal Wrappers</h3>
+<div class="paragraph">
+<p>While it is possible to simply interact with Java classes in a <code>ScriptEngine</code> implementation, such Gremlin language variants
+will not leverage the unique features of the host language. It is for this reason that <a href="https://github.com/mpollmeier/gremlin-scala">Gremlin-Scala</a>
+was developed. Scala provides many syntax niceties not available in Java. To leverage these niceties, Gremlin-Scala "wraps"
+<code>GraphTraversal</code> in order to provide Scala-idiomatic extensions. Another example is Apache TinkerPop&#8217;s
+Gremlin-Groovy which does the same via the <a href="http://tinkerpop.apache.org/docs/3.1.3-SNAPSHOT/reference/#sugar-plugin">Sugar plugin</a>,
+but uses <a href="http://groovy-lang.org/metaprogramming.html">meta-programming</a> instead of object wrapping.</p>
+</div>
+<div class="paragraph">
+<p>The Python (via Jython) classes below wrap <code>GraphTraversalSource</code> and <code>GraphTraversal</code>. In doing so, they add methods
+that apply Python-specific constructs to Gremlin. In particular, <code>__getitem__</code> and <code>__getattr__</code> "magic methods" are leveraged.
+It is important to note that the classes below are <strong>not complete</strong> and only provide enough functionality to demonstrate this
+sub-sections tutorial material.</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay"><code class="python language-python"><span class="comment"># GraphTraversalSource (incomplete)</span>
+<span class="keyword">class</span> <span class="class">JythonGraphTraversalSource</span>(<span class="predefined">object</span>):
+  <span class="keyword">def</span> <span class="function">__init__</span>(<span class="predefined-constant">self</span>, traversalSource):
+    <span class="predefined-constant">self</span>.traversalSource = traversalSource
+  <span class="keyword">def</span> <span class="function">V</span>(<span class="predefined-constant">self</span>,*args):
+    <span class="keyword">return</span> JythonGraphTraversal(<span class="predefined-constant">self</span>.traversalSource.V(*args))
+  <span class="keyword">def</span> <span class="function">__repr__</span>(<span class="predefined-constant">self</span>):
+    <span class="keyword">return</span> <span class="predefined-constant">self</span>.traversalSource.toString()
+
+<span class="comment"># GraphTraversal (incomplete)</span>
+<span class="keyword">class</span> <span class="class">JythonGraphTraversal</span>(<span class="predefined">object</span>):
+  <span class="keyword">def</span> <span class="function">__init__</span>(<span class="predefined-constant">self</span>, traversal):
+    <span class="predefined-constant">self</span>.traversal = traversal
+  <span class="keyword">def</span> <span class="function">V</span>(<span class="predefined-constant">self</span>,*args):
+    <span class="predefined-constant">self</span>.traversal = <span class="predefined-constant">self</span>.traversal.V(args)
+    <span class="keyword">return</span> <span class="predefined-constant">self</span>
+  <span class="keyword">def</span> <span class="function">values</span>(<span class="predefined-constant">self</span>, *propertyKeys):
+    <span class="predefined-constant">self</span>.traversal = <span class="predefined-constant">self</span>.traversal.values(propertyKeys)
+    <span class="keyword">return</span> <span class="predefined-constant">self</span>
+  <span class="keyword">def</span> <span class="function">toList</span>(<span class="predefined-constant">self</span>):
+    <span class="keyword">return</span> <span class="predefined-constant">self</span>.traversal.toList()
+  <span class="keyword">def</span> <span class="function">__repr__</span>(<span class="predefined-constant">self</span>):
+    <span class="keyword">return</span> <span class="predefined-constant">self</span>.traversal.toString()
+  <span class="keyword">def</span> <span class="function">__getitem__</span>(<span class="predefined-constant">self</span>,index):
+    <span class="keyword">if</span> <span class="predefined">type</span>(index) <span class="keyword">is</span> <span class="predefined">int</span>:
+      <span class="predefined-constant">self</span>.traversal = <span class="predefined-constant">self</span>.traversal.range(indices,indices+<span class="integer">1</span>)
+    <span class="keyword">elif</span> <span class="predefined">type</span>(index) <span class="keyword">is</span> <span class="predefined">slice</span>:
+        <span class="predefined-constant">self</span>.traversal = <span class="predefined-constant">self</span>.traversal.range(index.start,index.stop)
+    <span class="keyword">else</span>:
+        <span class="keyword">raise</span> <span class="exception">TypeError</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">index must be int or slice</span><span class="delimiter">&quot;</span></span>)
+    <span class="keyword">return</span> <span class="predefined-constant">self</span>
+  <span class="keyword">def</span> <span class="function">__getattr__</span>(<span class="predefined-constant">self</span>,key):
+    <span class="keyword">return</span> <span class="predefined-constant">self</span>.values(key)</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The two methods <code>__getitem__</code> and <code>__getattr__</code> support Python <em>slicing</em> and <em>object attribute interception</em>, respectively.
+In this way, the host language is able to use its native constructs with Gremlin.</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay"><code class="python language-python">&gt;&gt;&gt; graph
+tinkergraph[vertices:<span class="integer">6</span> edges:<span class="integer">6</span>]
+&gt;&gt;&gt; g = JythonGraphTraversalSource(graph.traversal())
+&gt;&gt;&gt; g
+graphtraversalsource[tinkergraph[vertices:<span class="integer">6</span> edges:<span class="integer">6</span>], standard]
+<span class="comment"># Python slices are converted into range()-steps</span>
+&gt;&gt;&gt; g.V()[<span class="integer">1</span>:<span class="integer">4</span>]
+[GraphStep(vertex,[]), RangeGlobalStep(<span class="integer">1</span>,<span class="integer">4</span>)]
+<span class="comment"># Python attribute selections are converted into values()-steps</span>
+&gt;&gt;&gt; g.V()[<span class="integer">1</span>:<span class="integer">4</span>].name
+[GraphStep(vertex,[]), RangeGlobalStep(<span class="integer">1</span>,<span class="integer">4</span>), PropertiesStep([name],value)]
+&gt;&gt;&gt; g.V()[<span class="integer">1</span>:<span class="integer">4</span>].name.toList()
+[vadas, lop, josh]</code></pre>
+</div>
+</div>
+<div class="admonitionblock important">
+<table>
+<tr>
+<td class="icon">
+<div class="title">Important</div>
+</td>
+<td class="content">
+Gremlin-Java serves as the standard/default representation of the Gremlin traversal language. Any Gremlin
+language variant <strong>must</strong> provide all the same functionality (methods) as <code>GraphTraversal</code>, but <strong>can</strong> extend it
+with host language specific constructs. This means that the extensions <strong>must</strong> compile to <code>GraphTraversal</code>-specific
+steps. A Gremlin language variant <strong>should not</strong> add steps/methods that do not exist in <code>GraphTraversal</code>. If such an extension
+is desired, the language variant designer should submit a proposal to <a href="http://tinkerpop.apache.org">Apache TinkerPop</a>
+to have the extension added to a future release of Gremlin.
+</td>
+</tr>
+</table>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_auto_generated_traversal_wrappers">Auto-Generated Traversal Wrappers</h3>
+<div class="paragraph">
+<p>In the previous example, only a subset of the <code>GraphTraversalSource</code> and <code>GraphTraversal</code> methods were implemented in the
+corresponding Jython-based Python classes. Unfortunately, adding the near 200 <code>GraphTraversal</code> methods to a wrapper is
+both tedious and error-prone. To alleviate this pain, Python classes can be dynamically created using Groovy and
+<a href="https://en.wikipedia.org/wiki/Reflection_(computer_programming)#Java">Java reflection</a>.
+The Groovy code for constructing the <code>JythonGraphTraversal</code> class source is reviewed below. By simply executing this code
+in the <a href="http://tinkerpop.apache.org/docs/3.1.3-SNAPSHOT/reference/#gremlin-console">Gremlin Console</a>, the <code>gremlin-jython.py</code> file
+is generated and can be used by Jython.</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay"><code class="groovy language-groovy">pythonClass = <span class="keyword">new</span> <span class="predefined-type">StringBuilder</span>();
+pythonClass.append(<span class="string"><span class="delimiter">&quot;</span><span class="content">from org.apache.tinkerpop.gremlin.process.traversal.dsl.graph import __ as anon</span><span class="char">\n</span><span class="char">\n</span><span class="delimiter">&quot;</span></span>)
+
+<span class="comment">//////////////////////////</span>
+<span class="comment">// GraphTraversalSource //</span>
+<span class="comment">//////////////////////////</span>
+methods = GraphTraversalSource.getMethods().collect{methodMap[<span class="local-variable">it</span>.name]} <span class="keyword">as</span> <span class="predefined-type">Set</span>; <span class="type">[]</span>
+pythonClass.append(
+<span class="string"><span class="delimiter">&quot;&quot;&quot;</span><span class="content">class JythonGraphTraversalSource(object):
+  def __init__(self, traversalSource):
+    self.traversalSource = traversalSource
+  def __repr__(self):
+    return self.traversalSource.toString()
+</span><span class="delimiter">&quot;&quot;&quot;</span></span>)
+methods.each{ method -&gt;
+  returnType = (GraphTraversalSource.getMethods() <span class="keyword">as</span> <span class="predefined-type">Set</span>).findAll{<span class="local-variable">it</span>.name.equals(method)}.collect{<span class="local-variable">it</span>.returnType}[<span class="integer">0</span>]
+  <span class="keyword">if</span>(<span class="predefined-constant">null</span> != returnType &amp;&amp; TraversalSource.isAssignableFrom(returnType)) {
+  pythonClass.append(
+<span class="string"><span class="delimiter">&quot;&quot;&quot;</span><span class="content">  def </span><span class="inline"><span class="inline-delimiter">${</span>method<span class="inline-delimiter">}</span></span><span class="content">(self, *args):
+    self.traversalSource = self.traversalSource.</span><span class="inline"><span class="inline-delimiter">${</span>method<span class="inline-delimiter">}</span></span><span class="content">(*args)
+    return self
+</span><span class="delimiter">&quot;&quot;&quot;</span></span>)
+  } <span class="keyword">else</span> <span class="keyword">if</span>(<span class="predefined-constant">null</span> != returnType &amp;&amp; Traversal.isAssignableFrom(returnType)) {
+  pythonClass.append(
+<span class="string"><span class="delimiter">&quot;&quot;&quot;</span><span class="content">  def </span><span class="inline"><span class="inline-delimiter">${</span>method<span class="inline-delimiter">}</span></span><span class="content">(self, *args):
+    return JythonGraphTraversal(self.traversalSource.</span><span class="inline"><span class="inline-delimiter">${</span>method<span class="inline-delimiter">}</span></span><span class="content">(*args))
+</span><span class="delimiter">&quot;&quot;&quot;</span></span>)
+  } <span class="keyword">else</span> {
+  pythonClass.append(
+<span class="string"><span class="delimiter">&quot;&quot;&quot;</span><span class="content">  def </span><span class="inline"><span class="inline-delimiter">${</span>method<span class="inline-delimiter">}</span></span><span class="content">(self, *args):
+    return self.traversalSource.</span><span class="inline"><span class="inline-delimiter">${</span>method<span class="inline-delimiter">}</span></span><span class="content">(*args)
+</span><span class="delimiter">&quot;&quot;&quot;</span></span>)
+  }
+}; <span class="type">[]</span>
+pythonClass.append(<span class="string"><span class="delimiter">&quot;</span><span class="char">\n</span><span class="char">\n</span><span class="delimiter">&quot;</span></span>)
+
+<span class="comment">////////////////////</span>
+<span class="comment">// GraphTraversal //</span>
+<span class="comment">////////////////////</span>
+methodMap = [<span class="keyword">as</span>:<span class="string"><span class="delimiter">&quot;</span><span class="content">_as</span><span class="delimiter">&quot;</span></span>,<span class="keyword">in</span>:<span class="string"><span class="delimiter">&quot;</span><span class="content">_in</span><span class="delimiter">&quot;</span></span>,<span class="key">and</span>:<span class="string"><span class="delimiter">&quot;</span><span class="content">_and</span><span class="delimiter">&quot;</span></span>,<span class="key">or</span>:<span class="string"><span class="delimiter">&quot;</span><span class="content">_or</span><span class="delimiter">&quot;</span></span>,<span class="key">is</span>:<span class="string"><span class="delimiter">&quot;</span><span class="content">_is</span><span class="delimiter">&quot;</span></span>,<span class="key">not</span>:<span class="string"><span class="delimiter">&quot;</span><span class="content">_not</span><span class="delimiter">&quot;</span></
 span>,<span class="key">from</span>:<span class="string"><span class="delimiter">&quot;</span><span class="content">_from</span><span class="delimiter">&quot;</span></span>].withDefault{ <span class="local-variable">it</span> }  <b>(1)</b>
+invertedMethodMap = [<span class="key">_as</span>:<span class="string"><span class="delimiter">&quot;</span><span class="content">as</span><span class="delimiter">&quot;</span></span>,<span class="key">_in</span>:<span class="string"><span class="delimiter">&quot;</span><span class="content">in</span><span class="delimiter">&quot;</span></span>,<span class="key">_and</span>:<span class="string"><span class="delimiter">&quot;</span><span class="content">and</span><span class="delimiter">&quot;</span></span>,<span class="key">_or</span>:<span class="string"><span class="delimiter">&quot;</span><span class="content">or</span><span class="delimiter">&quot;</span></span>,<span class="key">_is</span>:<span class="string"><span class="delimiter">&quot;</span><span class="content">is</span><span class="delimiter">&quot;</span></span>,<span class="key">_not</span>:<span class="string"><span class="delimiter">&quot;</span><span class="content">not</span><span class="delimiter">&quot;</span></
 span>,<span class="key">_from</span>:<span class="string"><span class="delimiter">&quot;</span><span class="content">from</span><span class="delimiter">&quot;</span></span>].withDefault{ <span class="local-variable">it</span> }
+pythonClass.append(                                                           <b>(2)</b>
+<span class="string"><span class="delimiter">&quot;&quot;&quot;</span><span class="content">class JythonGraphTraversal(object):
+  def __init__(self, traversal):
+    self.traversal = traversal
+  def __repr__(self):
+    return self.traversal.toString()
+  def __getitem__(self,index):
+    if type(index) is int:
+      self.traversal = self.traversal.range(indices,indices+1)
+    elif type(index) is slice:
+        self.traversal = self.traversal.range(index.start,index.stop)
+    else:
+        raise TypeError(&quot;index must be int or slice&quot;)
+    return self
+  def __getattr__(self,key):
+    return self.values(key)
+</span><span class="delimiter">&quot;&quot;&quot;</span></span>)
+methods = GraphTraversal.getMethods().collect{methodMap[<span class="local-variable">it</span>.name]} <span class="keyword">as</span> <span class="predefined-type">Set</span>; <span class="type">[]</span>  <b>(3)</b>
+methods.each{ method -&gt;
+  returnType = (GraphTraversal.getMethods() <span class="keyword">as</span> <span class="predefined-type">Set</span>).findAll{<span class="local-variable">it</span>.name.equals(method)}.collect{<span class="local-variable">it</span>.returnType}[<span class="integer">0</span>]
+  <span class="keyword">if</span>(<span class="predefined-constant">null</span> != returnType &amp;&amp; Traversal.isAssignableFrom(returnType)) {          <b>(4)</b>
+  pythonClass.append(
+<span class="string"><span class="delimiter">&quot;&quot;&quot;</span><span class="content">  def </span><span class="inline"><span class="inline-delimiter">${</span>method<span class="inline-delimiter">}</span></span><span class="content">(self, *args):
+    self.traversal = self.traversal.</span><span class="inline"><span class="inline-delimiter">${</span>invertedMethodMap[method]<span class="inline-delimiter">}</span></span><span class="content">(*args)
+    return self
+</span><span class="delimiter">&quot;&quot;&quot;</span></span>)
+  } <span class="keyword">else</span> {
+  pythonClass.append(                                                         <b>(5)</b>
+<span class="string"><span class="delimiter">&quot;&quot;&quot;</span><span class="content">  def </span><span class="inline"><span class="inline-delimiter">${</span>method<span class="inline-delimiter">}</span></span><span class="content">(self, *args):
+    return self.traversal.</span><span class="inline"><span class="inline-delimiter">${</span>invertedMethodMap[method]<span class="inline-delimiter">}</span></span><span class="content">(*args)
+</span><span class="delimiter">&quot;&quot;&quot;</span></span>)
+  }
+}; <span class="type">[]</span>
+pythonClass.append(<span class="string"><span class="delimiter">&quot;</span><span class="char">\n</span><span class="char">\n</span><span class="delimiter">&quot;</span></span>)
+
+<span class="comment">////////////////////////</span>
+<span class="comment">// AnonymousTraversal //</span>
+<span class="comment">////////////////////////</span>
+methods = __.getMethods().collect{methodMap[<span class="local-variable">it</span>.name]} <span class="keyword">as</span> <span class="predefined-type">Set</span>; <span class="type">[]</span>
+pythonClass.append(<span class="string"><span class="delimiter">&quot;</span><span class="content">class __(object):</span><span class="char">\n</span><span class="delimiter">&quot;</span></span>);
+methods.each{ method -&gt;
+  pythonClass.append(
+<span class="string"><span class="delimiter">&quot;&quot;&quot;</span><span class="content">  @staticmethod
+  def </span><span class="inline"><span class="inline-delimiter">${</span>method<span class="inline-delimiter">}</span></span><span class="content">(*args):
+    return anon.</span><span class="inline"><span class="inline-delimiter">${</span>invertedMethodMap[method]<span class="inline-delimiter">}</span></span><span class="content">(*args)
+</span><span class="delimiter">&quot;&quot;&quot;</span></span>)
+}; <span class="type">[]</span>
+pythonClass.append(<span class="string"><span class="delimiter">&quot;</span><span class="char">\n</span><span class="char">\n</span><span class="delimiter">&quot;</span></span>)
+
+<span class="comment">// save to a python file</span>
+file = <span class="keyword">new</span> <span class="predefined-type">File</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">/usr/local/apache-gremlin-console-3.1.3-SNAPSHOT-standalone/lib/gremlin-jython.py</span><span class="delimiter">&quot;</span></span>)
+file.delete()
+pythonClass.eachLine{ file.append(<span class="local-variable">it</span> + <span class="string"><span class="delimiter">&quot;</span><span class="char">\n</span><span class="delimiter">&quot;</span></span>) }</code></pre>
+</div>
+</div>
+<div class="colist arabic">
+<ol>
+<li>
+<p>There are numerous <code>GraphTraversal</code> step names that are reserved words in Python. Prefixing these steps with <code>_</code> is the chosen workaround.</p>
+</li>
+<li>
+<p>Add Gremlin-Jython specific methods to <code>JythonGraphTraversal</code>. These methods are idiomatic Python extensions, not step additions.</p>
+</li>
+<li>
+<p>Use Java reflection to get all the methods of <code>GraphTraversal</code>.</p>
+</li>
+<li>
+<p>If the method is a fluent traversal-method, then mutate the underlying/wrapped <code>GraphTraversal</code> instance accordingly.</p>
+</li>
+<li>
+<p>If the method is not a fluent traversal-method, return the result of applying the method.</p>
+</li>
+</ol>
+</div>
+<div class="paragraph">
+<p>From the Jython console, <code>gremlin-jython.py</code> is loaded and a complete Gremlin language variant is born: <strong>Gremlin-Jython</strong>.
+The generated file is available at <a href="../../resources/gremlin-jython.py">gremlin-jython.py</a>.</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay"><code class="python language-python">&gt;&gt;&gt; <span class="predefined">execfile</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">/usr/local/apache-gremlin-console-3.1.3-SNAPSHOT-standalone/lib/gremlin-jython.py</span><span class="delimiter">&quot;</span></span>)
+&gt;&gt;&gt; graph = TinkerFactory.createModern()
+&gt;&gt;&gt; g = JythonGraphTraversalSource(graph.traversal())
+<span class="comment"># using the Gremlin-Jython __getattr__ and __getitem__ extensions and anonymous traversals</span>
+&gt;&gt;&gt; g.V().repeat(__.both(<span class="string"><span class="delimiter">&quot;</span><span class="content">created</span><span class="delimiter">&quot;</span></span>)).times(<span class="integer">2</span>).name[<span class="integer">1</span>:<span class="integer">3</span>].path().toList()
+[[v[<span class="integer">1</span>], v[<span class="integer">3</span>], v[<span class="integer">4</span>], josh], [v[<span class="integer">1</span>], v[<span class="integer">3</span>], v[<span class="integer">6</span>], peter]]
+<span class="comment"># JythonGraphTraversalSource works as expected -- an example using Gremlin-Jython w/ OLAP</span>
+&gt;&gt;&gt; g = g.withComputer()
+&gt;&gt;&gt; g
+graphtraversalsource[tinkergraph[vertices:<span class="integer">6</span> edges:<span class="integer">6</span>], graphcomputer]
+&gt;&gt;&gt; g.V().repeat(__.both(<span class="string"><span class="delimiter">&quot;</span><span class="content">created</span><span class="delimiter">&quot;</span></span>)).times(<span class="integer">2</span>).name[<span class="integer">1</span>:<span class="integer">3</span>].path().toList()
+[[v[<span class="integer">3</span>], v[<span class="integer">4</span>], v[<span class="integer">5</span>], ripple], [v[<span class="integer">1</span>], v[<span class="integer">4</span>], v[<span class="integer">5</span>], ripple]]
+&gt;&gt;&gt;</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Gremlin-Jython was simple to create. Unfortunately, this simplicity is not without problems. These problems are itemized below.
+However, for the sake of this tutorial, the simple application of the technique was chosen.</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>The Gremlin-Jython API is non-informative as all methods take a tuple reference (<code>*args</code>).</p>
+<div class="ulist">
+<ul>
+<li>
+<p>The Gremlin-Java <a href="http://tinkerpop.apache.org/javadocs/3.1.3-SNAPSHOT/full/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html">JavaDoc</a> would be a sufficient guide to Gremlin-Jython (minus the extensions).</p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>Lambdas are not supported with, for example, <code>map(lambda x: x.get())</code> throwing an exception.</p>
+<div class="ulist">
+<ul>
+<li>
+<p>Type introspection with a typecast to a <code>java.util.function.Function</code> lambda wrapper would solve this problem.</p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p><code>__</code> is always required for anonymous traversals.</p>
+<div class="ulist">
+<ul>
+<li>
+<p>By placing the <code>@staticmethods</code> outside of the <code>__</code> Jython class, the methods would be globally scoped (analogous to <code>import static</code> in Java).</p>
+</li>
+</ul>
+</div>
+</li>
+</ul>
+</div>
+</div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="using-python-and-jni">Using Python and JNI</h2>
+<div class="sectionbody">
+
+</div>
+</div>
+<div class="sect1">
+<h2 id="using-python-and-gremlin-server">Using Python and GremlinServer</h2>
+<div class="sectionbody">
+
+</div>
+</div>
+</div>
+<div id="footer">
+<div id="footer-text">
+Last updated 2016-04-20 10:01:02 MDT
+</div>
+</div>
+</body>
+</html>



Mime
View raw message