Răsfoiți Sursa

Merge branch 'agile' of https://github.com/visuddhinanda/mint into agile

visuddhinanda 1 an în urmă
părinte
comite
0926c63321
41 a modificat fișierele cu 1851 adăugiri și 120 ștergeri
  1. 8 7
      dashboard/src/components/article/article.css
  2. 2 2
      dashboard/src/locales/zh-Hans/dict/index.ts
  3. 1 1
      dashboard/src/theme/antd.dark.css
  4. 5 0
      deploy/roles/mint-v2/tasks/dashboard.yml
  5. 4 2
      rpc/tutorials/php/.gitignore
  6. 19 0
      rpc/tutorials/php/GPBMetadata/Lily.php
  7. 25 0
      rpc/tutorials/php/GPBMetadata/Morus.php
  8. 32 0
      rpc/tutorials/php/Palm/Lily/V1/Article.php
  9. 32 0
      rpc/tutorials/php/Palm/Lily/V1/Book.php
  10. 108 0
      rpc/tutorials/php/Palm/Lily/V1/PandocTask.php
  11. 59 0
      rpc/tutorials/php/Palm/Lily/V1/PandocTask/Format.php
  12. 86 0
      rpc/tutorials/php/Palm/Lily/V1/PandocTask/Input.php
  13. 113 0
      rpc/tutorials/php/Palm/Lily/V1/PandocTask/Output.php
  14. 59 0
      rpc/tutorials/php/Palm/Lily/V1/Section.php
  15. 32 0
      rpc/tutorials/php/Palm/Lily/V1/Slideshow.php
  16. 66 0
      rpc/tutorials/php/Palm/Lily/V1/Style.php
  17. 35 0
      rpc/tutorials/php/Palm/Lily/V1/TeXLiveClient.php
  18. 297 0
      rpc/tutorials/php/Palm/Lily/V1/TeXLiveRequest.php
  19. 86 0
      rpc/tutorials/php/Palm/Lily/V1/TeXLiveResponse.php
  20. 43 0
      rpc/tutorials/php/Palm/Lily/V1/TeXLiveStub.php
  21. 123 0
      rpc/tutorials/php/Palm/Lily/V1/TeXLiveTask.php
  22. 113 0
      rpc/tutorials/php/Palm/Lily/V1/TeXLiveTask/Output.php
  23. 44 0
      rpc/tutorials/php/Palm/Lily/V1/TeXLiveTask/Output/Format.php
  24. 33 0
      rpc/tutorials/php/Palm/Morus/V1/MarkdownClient.php
  25. 41 0
      rpc/tutorials/php/Palm/Morus/V1/MarkdownStub.php
  26. 86 0
      rpc/tutorials/php/Palm/Morus/V1/MarkdownToHtmlRequest.php
  27. 59 0
      rpc/tutorials/php/Palm/Morus/V1/MarkdownToHtmlResponse.php
  28. 6 6
      rpc/tutorials/php/README.md
  29. 15 3
      rpc/tutorials/php/composer.json
  30. 0 11
      rpc/tutorials/php/config-orig.yml
  31. 0 88
      rpc/tutorials/php/lily.php
  32. 12 0
      rpc/tutorials/php/morus-client.orig.json
  33. 48 0
      rpc/tutorials/php/morus-client.php
  34. 96 0
      rpc/tutorials/php/queue-producer.php
  35. 7 0
      rpc/tutorials/php/queue.orig.json
  36. BIN
      rpc/tutorials/php/tex/coding.png
  37. 5 0
      rpc/tutorials/php/tex/foreword.tex
  38. 28 0
      rpc/tutorials/php/tex/main.tex
  39. 7 0
      rpc/tutorials/php/tex/postscript.tex
  40. 7 0
      rpc/tutorials/php/tex/section-1.tex
  41. 9 0
      rpc/tutorials/php/tex/section-2.tex

+ 8 - 7
dashboard/src/components/article/article.css

@@ -6,28 +6,29 @@ h5,
 h6 {
   font-weight: 700;
 }
-.pcd_article h2 {
+.pcd_article h1 {
   margin-top: 1em;
-  font-size: 28px;
+  font-size: 27px !important;
   border-bottom: 1px solid gray;
 }
 .pcd_article h2 {
   margin-top: 1em;
-  font-size: 22px;
+  font-size: 24px !important;
   border-bottom: 1px solid gray;
 }
 .pcd_article h3 {
   margin-top: 0.5em;
-  font-size: 16px;
+  font-size: 22px !important;
 }
 .pcd_article h4 {
-  font-size: 100%;
+  font-size: 20px !important;
 }
 .pcd_article h5 {
-  font-size: 100%;
+  font-size: 18px !important;
 }
 .pcd_article h6 {
-  font-size: 100%;
+  font-size: 16px !important;
+  font-weight: 700;
 }
 .pcd_article blockquote {
   margin-left: 1em;

+ 2 - 2
dashboard/src/locales/zh-Hans/dict/index.ts

@@ -54,8 +54,8 @@ const items = {
   "dict.fields.type.imp.short.label": "命令",
   "dict.fields.type.cond.label": "条件",
   "dict.fields.type.cond.short.label": "条件",
-  "dict.fields.type.opt.label": "愿望",
-  "dict.fields.type.opt.short.label": "愿望",
+  "dict.fields.type.opt.label": "潜能",
+  "dict.fields.type.opt.short.label": "",
   "dict.fields.type.pres.label": "现",
   "dict.fields.type.pres.short.label": "现",
   "dict.fields.type.aor.label": "过",

+ 1 - 1
dashboard/src/theme/antd.dark.css

@@ -72,7 +72,7 @@ h5,
 h6 {
   margin-top: 0;
   margin-bottom: 0.5em;
-  color: rgba(255, 255, 255, 0.85);
+  color: #000000d9;
   font-weight: 500;
 }
 p {

+ 5 - 0
deploy/roles/mint-v2/tasks/dashboard.yml

@@ -1,3 +1,8 @@
+- name: remove current dashboard folder
+  ansible.builtin.file:
+    path: "{{ app_deploy_root }}/dashboard/"
+    state: absent
+
 - name: upload dashboard
   ansible.builtin.copy:
     src: "{{ playbook_dir }}/../dashboard/build/"

+ 4 - 2
rpc/tutorials/php/.gitignore

@@ -1,4 +1,6 @@
+/tmp/
+/morus-client.json
+/queue.json
+
 /composer.lock
 /vendor/
-/lib/
-/config.yml

Fișier diff suprimat deoarece este prea mare
+ 19 - 0
rpc/tutorials/php/GPBMetadata/Lily.php


+ 25 - 0
rpc/tutorials/php/GPBMetadata/Morus.php

@@ -0,0 +1,25 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: morus.proto
+
+namespace GPBMetadata;
+
+class Morus
+{
+    public static $is_initialized = false;
+
+    public static function initOnce() {
+        $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
+
+        if (static::$is_initialized == true) {
+          return;
+        }
+        $pool->internalAddGeneratedFile(
+            "\x0A\xD6\x02\x0A\x0Bmorus.proto\x12\x0Dpalm.morus.v1\":\x0A\x15MarkdownToHtmlRequest\x12\x0F\x0A\x07payload\x18\x01 \x01(\x09\x12\x10\x0A\x08sanitize\x18\x02 \x01(\x08\")\x0A\x16MarkdownToHtmlResponse\x12\x0F\x0A\x07payload\x18\x01 \x01(\x092c\x0A\x08Markdown\x12W\x0A\x06ToHtml\x12\$.palm.morus.v1.MarkdownToHtmlRequest\x1A%.palm.morus.v1.MarkdownToHtmlResponse\"\x00Bd\x0A+com.github.saturn_xiv.palm.plugins.morus.v1P\x01Z3github.com/saturn-xiv/palm/atropa/morus/services/v2b\x06proto3"
+        , true);
+
+        static::$is_initialized = true;
+    }
+}
+

+ 32 - 0
rpc/tutorials/php/Palm/Lily/V1/Article.php

@@ -0,0 +1,32 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: lily.proto
+
+namespace Palm\Lily\V1;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>palm.lily.v1.Article</code>
+ */
+class Article extends \Google\Protobuf\Internal\Message
+{
+
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     * }
+     */
+    public function __construct($data = NULL) {
+        \GPBMetadata\Lily::initOnce();
+        parent::__construct($data);
+    }
+
+}
+

+ 32 - 0
rpc/tutorials/php/Palm/Lily/V1/Book.php

@@ -0,0 +1,32 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: lily.proto
+
+namespace Palm\Lily\V1;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>palm.lily.v1.Book</code>
+ */
+class Book extends \Google\Protobuf\Internal\Message
+{
+
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     * }
+     */
+    public function __construct($data = NULL) {
+        \GPBMetadata\Lily::initOnce();
+        parent::__construct($data);
+    }
+
+}
+

+ 108 - 0
rpc/tutorials/php/Palm/Lily/V1/PandocTask.php

@@ -0,0 +1,108 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: lily.proto
+
+namespace Palm\Lily\V1;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * https://pandoc.org/MANUAL.html
+ *
+ * Generated from protobuf message <code>palm.lily.v1.PandocTask</code>
+ */
+class PandocTask extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.PandocTask.Input input = 1;</code>
+     */
+    protected $input = null;
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.PandocTask.Output output = 2;</code>
+     */
+    protected $output = null;
+
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type \Palm\Lily\V1\PandocTask\Input $input
+     *     @type \Palm\Lily\V1\PandocTask\Output $output
+     * }
+     */
+    public function __construct($data = NULL) {
+        \GPBMetadata\Lily::initOnce();
+        parent::__construct($data);
+    }
+
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.PandocTask.Input input = 1;</code>
+     * @return \Palm\Lily\V1\PandocTask\Input|null
+     */
+    public function getInput()
+    {
+        return $this->input;
+    }
+
+    public function hasInput()
+    {
+        return isset($this->input);
+    }
+
+    public function clearInput()
+    {
+        unset($this->input);
+    }
+
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.PandocTask.Input input = 1;</code>
+     * @param \Palm\Lily\V1\PandocTask\Input $var
+     * @return $this
+     */
+    public function setInput($var)
+    {
+        GPBUtil::checkMessage($var, \Palm\Lily\V1\PandocTask\Input::class);
+        $this->input = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.PandocTask.Output output = 2;</code>
+     * @return \Palm\Lily\V1\PandocTask\Output|null
+     */
+    public function getOutput()
+    {
+        return $this->output;
+    }
+
+    public function hasOutput()
+    {
+        return isset($this->output);
+    }
+
+    public function clearOutput()
+    {
+        unset($this->output);
+    }
+
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.PandocTask.Output output = 2;</code>
+     * @param \Palm\Lily\V1\PandocTask\Output $var
+     * @return $this
+     */
+    public function setOutput($var)
+    {
+        GPBUtil::checkMessage($var, \Palm\Lily\V1\PandocTask\Output::class);
+        $this->output = $var;
+
+        return $this;
+    }
+
+}
+

+ 59 - 0
rpc/tutorials/php/Palm/Lily/V1/PandocTask/Format.php

@@ -0,0 +1,59 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: lily.proto
+
+namespace Palm\Lily\V1\PandocTask;
+
+use UnexpectedValueException;
+
+/**
+ * Protobuf type <code>palm.lily.v1.PandocTask.Format</code>
+ */
+class Format
+{
+    /**
+     * Generated from protobuf enum <code>Plain = 0;</code>
+     */
+    const Plain = 0;
+    /**
+     * Generated from protobuf enum <code>Markdown = 1;</code>
+     */
+    const Markdown = 1;
+    /**
+     * Generated from protobuf enum <code>Pdf = 2;</code>
+     */
+    const Pdf = 2;
+    /**
+     * Generated from protobuf enum <code>Docx = 3;</code>
+     */
+    const Docx = 3;
+
+    private static $valueToName = [
+        self::Plain => 'Plain',
+        self::Markdown => 'Markdown',
+        self::Pdf => 'Pdf',
+        self::Docx => 'Docx',
+    ];
+
+    public static function name($value)
+    {
+        if (!isset(self::$valueToName[$value])) {
+            throw new UnexpectedValueException(sprintf(
+                    'Enum %s has no name defined for value %s', __CLASS__, $value));
+        }
+        return self::$valueToName[$value];
+    }
+
+
+    public static function value($name)
+    {
+        $const = __CLASS__ . '::' . strtoupper($name);
+        if (!defined($const)) {
+            throw new UnexpectedValueException(sprintf(
+                    'Enum %s has no value defined for name %s', __CLASS__, $name));
+        }
+        return constant($const);
+    }
+}
+

+ 86 - 0
rpc/tutorials/php/Palm/Lily/V1/PandocTask/Input.php

@@ -0,0 +1,86 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: lily.proto
+
+namespace Palm\Lily\V1\PandocTask;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>palm.lily.v1.PandocTask.Input</code>
+ */
+class Input extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.PandocTask.Format format = 1;</code>
+     */
+    protected $format = 0;
+    /**
+     * Generated from protobuf field <code>bytes payload = 2;</code>
+     */
+    protected $payload = '';
+
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type int $format
+     *     @type string $payload
+     * }
+     */
+    public function __construct($data = NULL) {
+        \GPBMetadata\Lily::initOnce();
+        parent::__construct($data);
+    }
+
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.PandocTask.Format format = 1;</code>
+     * @return int
+     */
+    public function getFormat()
+    {
+        return $this->format;
+    }
+
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.PandocTask.Format format = 1;</code>
+     * @param int $var
+     * @return $this
+     */
+    public function setFormat($var)
+    {
+        GPBUtil::checkEnum($var, \Palm\Lily\V1\PandocTask\Format::class);
+        $this->format = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>bytes payload = 2;</code>
+     * @return string
+     */
+    public function getPayload()
+    {
+        return $this->payload;
+    }
+
+    /**
+     * Generated from protobuf field <code>bytes payload = 2;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setPayload($var)
+    {
+        GPBUtil::checkString($var, False);
+        $this->payload = $var;
+
+        return $this;
+    }
+
+}
+

+ 113 - 0
rpc/tutorials/php/Palm/Lily/V1/PandocTask/Output.php

@@ -0,0 +1,113 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: lily.proto
+
+namespace Palm\Lily\V1\PandocTask;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>palm.lily.v1.PandocTask.Output</code>
+ */
+class Output extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.PandocTask.Format format = 1;</code>
+     */
+    protected $format = 0;
+    /**
+     * Generated from protobuf field <code>string bucket = 2;</code>
+     */
+    protected $bucket = '';
+    /**
+     * Generated from protobuf field <code>string object = 3;</code>
+     */
+    protected $object = '';
+
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type int $format
+     *     @type string $bucket
+     *     @type string $object
+     * }
+     */
+    public function __construct($data = NULL) {
+        \GPBMetadata\Lily::initOnce();
+        parent::__construct($data);
+    }
+
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.PandocTask.Format format = 1;</code>
+     * @return int
+     */
+    public function getFormat()
+    {
+        return $this->format;
+    }
+
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.PandocTask.Format format = 1;</code>
+     * @param int $var
+     * @return $this
+     */
+    public function setFormat($var)
+    {
+        GPBUtil::checkEnum($var, \Palm\Lily\V1\PandocTask\Format::class);
+        $this->format = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>string bucket = 2;</code>
+     * @return string
+     */
+    public function getBucket()
+    {
+        return $this->bucket;
+    }
+
+    /**
+     * Generated from protobuf field <code>string bucket = 2;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setBucket($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->bucket = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>string object = 3;</code>
+     * @return string
+     */
+    public function getObject()
+    {
+        return $this->object;
+    }
+
+    /**
+     * Generated from protobuf field <code>string object = 3;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setObject($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->object = $var;
+
+        return $this;
+    }
+
+}
+

+ 59 - 0
rpc/tutorials/php/Palm/Lily/V1/Section.php

@@ -0,0 +1,59 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: lily.proto
+
+namespace Palm\Lily\V1;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>palm.lily.v1.Section</code>
+ */
+class Section extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * Generated from protobuf field <code>repeated .palm.lily.v1.Section items = 1;</code>
+     */
+    private $items;
+
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type array<\Palm\Lily\V1\Section>|\Google\Protobuf\Internal\RepeatedField $items
+     * }
+     */
+    public function __construct($data = NULL) {
+        \GPBMetadata\Lily::initOnce();
+        parent::__construct($data);
+    }
+
+    /**
+     * Generated from protobuf field <code>repeated .palm.lily.v1.Section items = 1;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
+     */
+    public function getItems()
+    {
+        return $this->items;
+    }
+
+    /**
+     * Generated from protobuf field <code>repeated .palm.lily.v1.Section items = 1;</code>
+     * @param array<\Palm\Lily\V1\Section>|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
+     */
+    public function setItems($var)
+    {
+        $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Palm\Lily\V1\Section::class);
+        $this->items = $arr;
+
+        return $this;
+    }
+
+}
+

+ 32 - 0
rpc/tutorials/php/Palm/Lily/V1/Slideshow.php

@@ -0,0 +1,32 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: lily.proto
+
+namespace Palm\Lily\V1;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>palm.lily.v1.Slideshow</code>
+ */
+class Slideshow extends \Google\Protobuf\Internal\Message
+{
+
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     * }
+     */
+    public function __construct($data = NULL) {
+        \GPBMetadata\Lily::initOnce();
+        parent::__construct($data);
+    }
+
+}
+

+ 66 - 0
rpc/tutorials/php/Palm/Lily/V1/Style.php

@@ -0,0 +1,66 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: lily.proto
+
+namespace Palm\Lily\V1;
+
+use UnexpectedValueException;
+
+/**
+ * https://owl.purdue.edu/owl/general_writing/general_writing_faqs.html
+ *
+ * Protobuf type <code>palm.lily.v1.Style</code>
+ */
+class Style
+{
+    /**
+     * https://apastyle.apa.org/
+     * https://owl.purdue.edu/owl/research_and_citation/apa_style/apa_formatting_and_style_guide/general_format.html
+     * https://www.ilc.cuhk.edu.hk/Chinese/APAMLA/APA/APAlayout.aspx
+     *
+     * Generated from protobuf enum <code>APA_7 = 0;</code>
+     */
+    const APA_7 = 0;
+    /**
+     * https://www.mla.org/MLA-Style
+     * https://owl.purdue.edu/owl/research_and_citation/mla_style/mla_formatting_and_style_guide/mla_formatting_and_style_guide.html#:~:text=MLA%20(Modern%20Language%20Association)%20style,the%20liberal%20arts%20and%20humanities.
+     *
+     * Generated from protobuf enum <code>MLA_8 = 10;</code>
+     */
+    const MLA_8 = 10;
+    /**
+     * https://www.chicagomanualofstyle.org/home.html
+     * https://owl.purdue.edu/owl/research_and_citation/chicago_manual_17th_edition/cmos_formatting_and_style_guide/chicago_manual_of_style_17th_edition.html
+     *
+     * Generated from protobuf enum <code>CMOS = 20;</code>
+     */
+    const CMOS = 20;
+
+    private static $valueToName = [
+        self::APA_7 => 'APA_7',
+        self::MLA_8 => 'MLA_8',
+        self::CMOS => 'CMOS',
+    ];
+
+    public static function name($value)
+    {
+        if (!isset(self::$valueToName[$value])) {
+            throw new UnexpectedValueException(sprintf(
+                    'Enum %s has no name defined for value %s', __CLASS__, $value));
+        }
+        return self::$valueToName[$value];
+    }
+
+
+    public static function value($name)
+    {
+        $const = __CLASS__ . '::' . strtoupper($name);
+        if (!defined($const)) {
+            throw new UnexpectedValueException(sprintf(
+                    'Enum %s has no value defined for name %s', __CLASS__, $name));
+        }
+        return constant($const);
+    }
+}
+

+ 35 - 0
rpc/tutorials/php/Palm/Lily/V1/TeXLiveClient.php

@@ -0,0 +1,35 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+namespace Palm\Lily\V1;
+
+/**
+ * ----------------------------------------------------------------------------
+ *
+ */
+class TeXLiveClient extends \Grpc\BaseStub {
+
+    /**
+     * @param string $hostname hostname
+     * @param array $opts channel options
+     * @param \Grpc\Channel $channel (optional) re-use channel object
+     */
+    public function __construct($hostname, $opts, $channel = null) {
+        parent::__construct($hostname, $opts, $channel);
+    }
+
+    /**
+     * @param \Palm\Lily\V1\TeXLiveRequest $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     * @return \Grpc\UnaryCall
+     */
+    public function ToPdf(\Palm\Lily\V1\TeXLiveRequest $argument,
+      $metadata = [], $options = []) {
+        return $this->_simpleRequest('/palm.lily.v1.TeXLive/ToPdf',
+        $argument,
+        ['\Palm\Lily\V1\TeXLiveResponse', 'decode'],
+        $metadata, $options);
+    }
+
+}

+ 297 - 0
rpc/tutorials/php/Palm/Lily/V1/TeXLiveRequest.php

@@ -0,0 +1,297 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: lily.proto
+
+namespace Palm\Lily\V1;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>palm.lily.v1.TeXLiveRequest</code>
+ */
+class TeXLiveRequest extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * Generated from protobuf field <code>string name = 1;</code>
+     */
+    protected $name = '';
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.Style style = 2;</code>
+     */
+    protected $style = 0;
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.TeXLiveTask.Output.Format format = 3;</code>
+     */
+    protected $format = 0;
+    /**
+     * Generated from protobuf field <code>.google.protobuf.Duration ttl = 9;</code>
+     */
+    protected $ttl = null;
+    /**
+     * Generated from protobuf field <code>bytes entry = 98;</code>
+     */
+    protected $entry = '';
+    /**
+     * Generated from protobuf field <code>map<string, bytes> attachments = 99;</code>
+     */
+    private $attachments;
+    protected $Payload;
+
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $name
+     *     @type int $style
+     *     @type int $format
+     *     @type \Google\Protobuf\Duration $ttl
+     *     @type \Palm\Lily\V1\Book $book
+     *     @type \Palm\Lily\V1\Article $article
+     *     @type \Palm\Lily\V1\Slideshow $slideshow
+     *     @type string $entry
+     *     @type array|\Google\Protobuf\Internal\MapField $attachments
+     * }
+     */
+    public function __construct($data = NULL) {
+        \GPBMetadata\Lily::initOnce();
+        parent::__construct($data);
+    }
+
+    /**
+     * Generated from protobuf field <code>string name = 1;</code>
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * Generated from protobuf field <code>string name = 1;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setName($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->name = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.Style style = 2;</code>
+     * @return int
+     */
+    public function getStyle()
+    {
+        return $this->style;
+    }
+
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.Style style = 2;</code>
+     * @param int $var
+     * @return $this
+     */
+    public function setStyle($var)
+    {
+        GPBUtil::checkEnum($var, \Palm\Lily\V1\Style::class);
+        $this->style = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.TeXLiveTask.Output.Format format = 3;</code>
+     * @return int
+     */
+    public function getFormat()
+    {
+        return $this->format;
+    }
+
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.TeXLiveTask.Output.Format format = 3;</code>
+     * @param int $var
+     * @return $this
+     */
+    public function setFormat($var)
+    {
+        GPBUtil::checkEnum($var, \Palm\Lily\V1\TeXLiveTask\Output\Format::class);
+        $this->format = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>.google.protobuf.Duration ttl = 9;</code>
+     * @return \Google\Protobuf\Duration|null
+     */
+    public function getTtl()
+    {
+        return $this->ttl;
+    }
+
+    public function hasTtl()
+    {
+        return isset($this->ttl);
+    }
+
+    public function clearTtl()
+    {
+        unset($this->ttl);
+    }
+
+    /**
+     * Generated from protobuf field <code>.google.protobuf.Duration ttl = 9;</code>
+     * @param \Google\Protobuf\Duration $var
+     * @return $this
+     */
+    public function setTtl($var)
+    {
+        GPBUtil::checkMessage($var, \Google\Protobuf\Duration::class);
+        $this->ttl = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.Book book = 11;</code>
+     * @return \Palm\Lily\V1\Book|null
+     */
+    public function getBook()
+    {
+        return $this->readOneof(11);
+    }
+
+    public function hasBook()
+    {
+        return $this->hasOneof(11);
+    }
+
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.Book book = 11;</code>
+     * @param \Palm\Lily\V1\Book $var
+     * @return $this
+     */
+    public function setBook($var)
+    {
+        GPBUtil::checkMessage($var, \Palm\Lily\V1\Book::class);
+        $this->writeOneof(11, $var);
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.Article article = 12;</code>
+     * @return \Palm\Lily\V1\Article|null
+     */
+    public function getArticle()
+    {
+        return $this->readOneof(12);
+    }
+
+    public function hasArticle()
+    {
+        return $this->hasOneof(12);
+    }
+
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.Article article = 12;</code>
+     * @param \Palm\Lily\V1\Article $var
+     * @return $this
+     */
+    public function setArticle($var)
+    {
+        GPBUtil::checkMessage($var, \Palm\Lily\V1\Article::class);
+        $this->writeOneof(12, $var);
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.Slideshow slideshow = 13;</code>
+     * @return \Palm\Lily\V1\Slideshow|null
+     */
+    public function getSlideshow()
+    {
+        return $this->readOneof(13);
+    }
+
+    public function hasSlideshow()
+    {
+        return $this->hasOneof(13);
+    }
+
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.Slideshow slideshow = 13;</code>
+     * @param \Palm\Lily\V1\Slideshow $var
+     * @return $this
+     */
+    public function setSlideshow($var)
+    {
+        GPBUtil::checkMessage($var, \Palm\Lily\V1\Slideshow::class);
+        $this->writeOneof(13, $var);
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>bytes entry = 98;</code>
+     * @return string
+     */
+    public function getEntry()
+    {
+        return $this->entry;
+    }
+
+    /**
+     * Generated from protobuf field <code>bytes entry = 98;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setEntry($var)
+    {
+        GPBUtil::checkString($var, False);
+        $this->entry = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>map<string, bytes> attachments = 99;</code>
+     * @return \Google\Protobuf\Internal\MapField
+     */
+    public function getAttachments()
+    {
+        return $this->attachments;
+    }
+
+    /**
+     * Generated from protobuf field <code>map<string, bytes> attachments = 99;</code>
+     * @param array|\Google\Protobuf\Internal\MapField $var
+     * @return $this
+     */
+    public function setAttachments($var)
+    {
+        $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::BYTES);
+        $this->attachments = $arr;
+
+        return $this;
+    }
+
+    /**
+     * @return string
+     */
+    public function getPayload()
+    {
+        return $this->whichOneof("Payload");
+    }
+
+}
+

+ 86 - 0
rpc/tutorials/php/Palm/Lily/V1/TeXLiveResponse.php

@@ -0,0 +1,86 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: lily.proto
+
+namespace Palm\Lily\V1;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>palm.lily.v1.TeXLiveResponse</code>
+ */
+class TeXLiveResponse extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * Generated from protobuf field <code>string bucket = 1;</code>
+     */
+    protected $bucket = '';
+    /**
+     * Generated from protobuf field <code>string object = 2;</code>
+     */
+    protected $object = '';
+
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $bucket
+     *     @type string $object
+     * }
+     */
+    public function __construct($data = NULL) {
+        \GPBMetadata\Lily::initOnce();
+        parent::__construct($data);
+    }
+
+    /**
+     * Generated from protobuf field <code>string bucket = 1;</code>
+     * @return string
+     */
+    public function getBucket()
+    {
+        return $this->bucket;
+    }
+
+    /**
+     * Generated from protobuf field <code>string bucket = 1;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setBucket($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->bucket = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>string object = 2;</code>
+     * @return string
+     */
+    public function getObject()
+    {
+        return $this->object;
+    }
+
+    /**
+     * Generated from protobuf field <code>string object = 2;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setObject($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->object = $var;
+
+        return $this;
+    }
+
+}
+

+ 43 - 0
rpc/tutorials/php/Palm/Lily/V1/TeXLiveStub.php

@@ -0,0 +1,43 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+namespace Palm\Lily\V1;
+
+/**
+ * ----------------------------------------------------------------------------
+ *
+ */
+class TeXLiveStub {
+
+    /**
+     * @param \Palm\Lily\V1\TeXLiveRequest $request client request
+     * @param \Grpc\ServerContext $context server request context
+     * @return \Palm\Lily\V1\TeXLiveResponse for response data, null if if error occured
+     *     initial metadata (if any) and status (if not ok) should be set to $context
+     */
+    public function ToPdf(
+        \Palm\Lily\V1\TeXLiveRequest $request,
+        \Grpc\ServerContext $context
+    ): ?\Palm\Lily\V1\TeXLiveResponse {
+        $context->setStatus(\Grpc\Status::unimplemented());
+        return null;
+    }
+
+    /**
+     * Get the method descriptors of the service for server registration
+     *
+     * @return array of \Grpc\MethodDescriptor for the service methods
+     */
+    public final function getMethodDescriptors(): array
+    {
+        return [
+            '/palm.lily.v1.TeXLive/ToPdf' => new \Grpc\MethodDescriptor(
+                $this,
+                'ToPdf',
+                '\Palm\Lily\V1\TeXLiveRequest',
+                \Grpc\MethodDescriptor::UNARY_CALL
+            ),
+        ];
+    }
+
+}

+ 123 - 0
rpc/tutorials/php/Palm/Lily/V1/TeXLiveTask.php

@@ -0,0 +1,123 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: lily.proto
+
+namespace Palm\Lily\V1;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>palm.lily.v1.TeXLiveTask</code>
+ */
+class TeXLiveTask extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * Generated from protobuf field <code>bytes entry = 1;</code>
+     */
+    protected $entry = '';
+    /**
+     * Generated from protobuf field <code>map<string, bytes> attachments = 3;</code>
+     */
+    private $attachments;
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.TeXLiveTask.Output output = 9;</code>
+     */
+    protected $output = null;
+
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $entry
+     *     @type array|\Google\Protobuf\Internal\MapField $attachments
+     *     @type \Palm\Lily\V1\TeXLiveTask\Output $output
+     * }
+     */
+    public function __construct($data = NULL) {
+        \GPBMetadata\Lily::initOnce();
+        parent::__construct($data);
+    }
+
+    /**
+     * Generated from protobuf field <code>bytes entry = 1;</code>
+     * @return string
+     */
+    public function getEntry()
+    {
+        return $this->entry;
+    }
+
+    /**
+     * Generated from protobuf field <code>bytes entry = 1;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setEntry($var)
+    {
+        GPBUtil::checkString($var, False);
+        $this->entry = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>map<string, bytes> attachments = 3;</code>
+     * @return \Google\Protobuf\Internal\MapField
+     */
+    public function getAttachments()
+    {
+        return $this->attachments;
+    }
+
+    /**
+     * Generated from protobuf field <code>map<string, bytes> attachments = 3;</code>
+     * @param array|\Google\Protobuf\Internal\MapField $var
+     * @return $this
+     */
+    public function setAttachments($var)
+    {
+        $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::BYTES);
+        $this->attachments = $arr;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.TeXLiveTask.Output output = 9;</code>
+     * @return \Palm\Lily\V1\TeXLiveTask\Output|null
+     */
+    public function getOutput()
+    {
+        return $this->output;
+    }
+
+    public function hasOutput()
+    {
+        return isset($this->output);
+    }
+
+    public function clearOutput()
+    {
+        unset($this->output);
+    }
+
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.TeXLiveTask.Output output = 9;</code>
+     * @param \Palm\Lily\V1\TeXLiveTask\Output $var
+     * @return $this
+     */
+    public function setOutput($var)
+    {
+        GPBUtil::checkMessage($var, \Palm\Lily\V1\TeXLiveTask\Output::class);
+        $this->output = $var;
+
+        return $this;
+    }
+
+}
+

+ 113 - 0
rpc/tutorials/php/Palm/Lily/V1/TeXLiveTask/Output.php

@@ -0,0 +1,113 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: lily.proto
+
+namespace Palm\Lily\V1\TeXLiveTask;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>palm.lily.v1.TeXLiveTask.Output</code>
+ */
+class Output extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.TeXLiveTask.Output.Format format = 1;</code>
+     */
+    protected $format = 0;
+    /**
+     * Generated from protobuf field <code>string bucket = 2;</code>
+     */
+    protected $bucket = '';
+    /**
+     * Generated from protobuf field <code>string object = 3;</code>
+     */
+    protected $object = '';
+
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type int $format
+     *     @type string $bucket
+     *     @type string $object
+     * }
+     */
+    public function __construct($data = NULL) {
+        \GPBMetadata\Lily::initOnce();
+        parent::__construct($data);
+    }
+
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.TeXLiveTask.Output.Format format = 1;</code>
+     * @return int
+     */
+    public function getFormat()
+    {
+        return $this->format;
+    }
+
+    /**
+     * Generated from protobuf field <code>.palm.lily.v1.TeXLiveTask.Output.Format format = 1;</code>
+     * @param int $var
+     * @return $this
+     */
+    public function setFormat($var)
+    {
+        GPBUtil::checkEnum($var, \Palm\Lily\V1\TeXLiveTask\Output\Format::class);
+        $this->format = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>string bucket = 2;</code>
+     * @return string
+     */
+    public function getBucket()
+    {
+        return $this->bucket;
+    }
+
+    /**
+     * Generated from protobuf field <code>string bucket = 2;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setBucket($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->bucket = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>string object = 3;</code>
+     * @return string
+     */
+    public function getObject()
+    {
+        return $this->object;
+    }
+
+    /**
+     * Generated from protobuf field <code>string object = 3;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setObject($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->object = $var;
+
+        return $this;
+    }
+
+}
+

+ 44 - 0
rpc/tutorials/php/Palm/Lily/V1/TeXLiveTask/Output/Format.php

@@ -0,0 +1,44 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: lily.proto
+
+namespace Palm\Lily\V1\TeXLiveTask\Output;
+
+use UnexpectedValueException;
+
+/**
+ * Protobuf type <code>palm.lily.v1.TeXLiveTask.Output.Format</code>
+ */
+class Format
+{
+    /**
+     * Generated from protobuf enum <code>Pdf = 0;</code>
+     */
+    const Pdf = 0;
+
+    private static $valueToName = [
+        self::Pdf => 'Pdf',
+    ];
+
+    public static function name($value)
+    {
+        if (!isset(self::$valueToName[$value])) {
+            throw new UnexpectedValueException(sprintf(
+                    'Enum %s has no name defined for value %s', __CLASS__, $value));
+        }
+        return self::$valueToName[$value];
+    }
+
+
+    public static function value($name)
+    {
+        $const = __CLASS__ . '::' . strtoupper($name);
+        if (!defined($const)) {
+            throw new UnexpectedValueException(sprintf(
+                    'Enum %s has no value defined for name %s', __CLASS__, $name));
+        }
+        return constant($const);
+    }
+}
+

+ 33 - 0
rpc/tutorials/php/Palm/Morus/V1/MarkdownClient.php

@@ -0,0 +1,33 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+namespace Palm\Morus\V1;
+
+/**
+ */
+class MarkdownClient extends \Grpc\BaseStub {
+
+    /**
+     * @param string $hostname hostname
+     * @param array $opts channel options
+     * @param \Grpc\Channel $channel (optional) re-use channel object
+     */
+    public function __construct($hostname, $opts, $channel = null) {
+        parent::__construct($hostname, $opts, $channel);
+    }
+
+    /**
+     * @param \Palm\Morus\V1\MarkdownToHtmlRequest $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     * @return \Grpc\UnaryCall
+     */
+    public function ToHtml(\Palm\Morus\V1\MarkdownToHtmlRequest $argument,
+      $metadata = [], $options = []) {
+        return $this->_simpleRequest('/palm.morus.v1.Markdown/ToHtml',
+        $argument,
+        ['\Palm\Morus\V1\MarkdownToHtmlResponse', 'decode'],
+        $metadata, $options);
+    }
+
+}

+ 41 - 0
rpc/tutorials/php/Palm/Morus/V1/MarkdownStub.php

@@ -0,0 +1,41 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+namespace Palm\Morus\V1;
+
+/**
+ */
+class MarkdownStub {
+
+    /**
+     * @param \Palm\Morus\V1\MarkdownToHtmlRequest $request client request
+     * @param \Grpc\ServerContext $context server request context
+     * @return \Palm\Morus\V1\MarkdownToHtmlResponse for response data, null if if error occured
+     *     initial metadata (if any) and status (if not ok) should be set to $context
+     */
+    public function ToHtml(
+        \Palm\Morus\V1\MarkdownToHtmlRequest $request,
+        \Grpc\ServerContext $context
+    ): ?\Palm\Morus\V1\MarkdownToHtmlResponse {
+        $context->setStatus(\Grpc\Status::unimplemented());
+        return null;
+    }
+
+    /**
+     * Get the method descriptors of the service for server registration
+     *
+     * @return array of \Grpc\MethodDescriptor for the service methods
+     */
+    public final function getMethodDescriptors(): array
+    {
+        return [
+            '/palm.morus.v1.Markdown/ToHtml' => new \Grpc\MethodDescriptor(
+                $this,
+                'ToHtml',
+                '\Palm\Morus\V1\MarkdownToHtmlRequest',
+                \Grpc\MethodDescriptor::UNARY_CALL
+            ),
+        ];
+    }
+
+}

+ 86 - 0
rpc/tutorials/php/Palm/Morus/V1/MarkdownToHtmlRequest.php

@@ -0,0 +1,86 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: morus.proto
+
+namespace Palm\Morus\V1;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>palm.morus.v1.MarkdownToHtmlRequest</code>
+ */
+class MarkdownToHtmlRequest extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * Generated from protobuf field <code>string payload = 1;</code>
+     */
+    protected $payload = '';
+    /**
+     * Generated from protobuf field <code>bool sanitize = 2;</code>
+     */
+    protected $sanitize = false;
+
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $payload
+     *     @type bool $sanitize
+     * }
+     */
+    public function __construct($data = NULL) {
+        \GPBMetadata\Morus::initOnce();
+        parent::__construct($data);
+    }
+
+    /**
+     * Generated from protobuf field <code>string payload = 1;</code>
+     * @return string
+     */
+    public function getPayload()
+    {
+        return $this->payload;
+    }
+
+    /**
+     * Generated from protobuf field <code>string payload = 1;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setPayload($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->payload = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>bool sanitize = 2;</code>
+     * @return bool
+     */
+    public function getSanitize()
+    {
+        return $this->sanitize;
+    }
+
+    /**
+     * Generated from protobuf field <code>bool sanitize = 2;</code>
+     * @param bool $var
+     * @return $this
+     */
+    public function setSanitize($var)
+    {
+        GPBUtil::checkBool($var);
+        $this->sanitize = $var;
+
+        return $this;
+    }
+
+}
+

+ 59 - 0
rpc/tutorials/php/Palm/Morus/V1/MarkdownToHtmlResponse.php

@@ -0,0 +1,59 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
+# source: morus.proto
+
+namespace Palm\Morus\V1;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Generated from protobuf message <code>palm.morus.v1.MarkdownToHtmlResponse</code>
+ */
+class MarkdownToHtmlResponse extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * Generated from protobuf field <code>string payload = 1;</code>
+     */
+    protected $payload = '';
+
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type string $payload
+     * }
+     */
+    public function __construct($data = NULL) {
+        \GPBMetadata\Morus::initOnce();
+        parent::__construct($data);
+    }
+
+    /**
+     * Generated from protobuf field <code>string payload = 1;</code>
+     * @return string
+     */
+    public function getPayload()
+    {
+        return $this->payload;
+    }
+
+    /**
+     * Generated from protobuf field <code>string payload = 1;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setPayload($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->payload = $var;
+
+        return $this;
+    }
+
+}
+

+ 6 - 6
rpc/tutorials/php/README.md

@@ -1,9 +1,9 @@
-# USAGE
-
-- install [php-pear](https://aur.archlinux.org/packages/php-pear)
+# Usage
 
 ```bash
-# add "extension=yaml" to php.ini
-sudo pecl install yaml
-composer update
+composer install
+
+php -d extension=grpc.so -d max_execution_time=300 morus-client.php morus.json
+php queue-producer.php queue.json texlive QUEUE
+php queue-producer.php queue.json pandoc QUEUE
 ```

+ 15 - 3
rpc/tutorials/php/composer.json

@@ -1,7 +1,19 @@
 {
+  "name": "grpc/grpc-demo",
+  "description": "gRPC example for PHP",
   "require": {
-    "php-amqplib/php-amqplib": "^3.2",
-    "apache/thrift": "0.20.0",
-    "monolog/monolog": "3.6.0"
+    "grpc/grpc": "^v1.39.0",
+    "google/protobuf": "^v3.12.2",
+    "monolog/monolog": "^3.7",
+    "ramsey/uuid": "^4.7",
+    "php-amqplib/php-amqplib": "^3.7"
+  },
+  "autoload": {
+    "psr-4": {
+      "GPBMetadata\\": [
+        "GPBMetadata/"
+      ],
+      "Palm\\": "Palm/"
+    }
   }
 }

+ 0 - 11
rpc/tutorials/php/config-orig.yml

@@ -1,11 +0,0 @@
-rabbitmq:
-  host: "127.0.0.1"
-  port: 5672
-  user: "guest"
-  password: "guest"
-  virtual-host: "testing"
-
-lily:
-  tex-to-pdf:
-    queue-name: "tex2pdf"
-    callback-url: "http://localhost:8080/md2pdf/callback"

+ 0 - 88
rpc/tutorials/php/lily.php

@@ -1,88 +0,0 @@
-<?php
-
-require_once __DIR__ . '/vendor/autoload.php';
-require_once __DIR__ . '/lib/lily/Tex.php';
-require_once __DIR__ . '/lib/lily/TexToPdfTask.php';
-
-
-use Monolog\Level;
-use Monolog\Logger;
-use Monolog\Handler\StreamHandler;
-use Thrift\Serializer\TBinarySerializer;
-use PhpAmqpLib\Connection\AMQPStreamConnection;
-use PhpAmqpLib\Message\AMQPMessage;
-
-
-use lily\Tex;
-use lily\TexToPdfTask;
-
-function publish_tex_to_pdf($logger, $channel, $queue, $callback)
-{
-    $task = new TexToPdfTask();
-    $task->bucket = "testing";
-    $task->object = date("Y-m-d") . '.pdf';
-    $task->callback = $callback;
-    $task->tex = new Tex();
-    $task->tex->homepage = <<<TEX
-\\documentclass{article}
-
-\\begin{document}
-
-\\title{The title \\thanks{With footnote}}
-\\auhtor{me}
-\\date{\\today}
-\\maketitle
-
-\\include{vocabulary/session-1.tex}
-\\include{vocabulary/session-2.tex}
-\\include{vocabulary/session-3.tex}
-
-\\end {document}
-TEX;
-    $task->tex->files = array(
-        "section-1.tex" => <<<TEX
-\\section{Session 1}
-TEX,
-        "section-2.tex" => <<<TEX
-\\section{Session 2}        
-
-\\First\\footnote{First note}
-\\Second\\footnote{Second note}
-\\Third\\footnote{Third note}
-TEX,
-        "section-3.tex" => <<<TEX
-\\section{Session 3}
-TEX,
-    );
-
-    $body = TBinarySerializer::serialize($task);
-    $message_id = uniqid();
-    $logger->debug("publish a tex-to-pdf task(" . strlen($body)  . "bytes) " . $message_id);
-    // https://github.com/php-amqplib/php-amqplib/blob/master/doc/AMQPMessage.md
-    $message = new AMQPMessage($body, ['message_id' => $message_id]);
-    $channel->basic_publish($message, '', $queue);
-}
-
-$logger = new Logger('lily');
-$logger->pushHandler(new StreamHandler('php://stdout', Level::Debug));
-$logger->debug("run on debug mode");
-
-if ($argc !== 2) {
-    $logger->error("usage: php $argv[0] config.yml");
-    exit(1);
-}
-$logger->debug("$argc");
-$logger->info("load config from" . $argv[1]);
-$config = yaml_parse_file($argv[1]);
-$logger->debug("connect to rabbitmq://" . $config['rabbitmq']['host'] . "@" . $config['rabbitmq']['host'] . ":" . $config['rabbitmq']['port'] . "/" . $config['rabbitmq']['virtual-host']);
-
-$queue_connection = new AMQPStreamConnection($config['rabbitmq']['host'], $config['rabbitmq']['port'], $config['rabbitmq']['user'], $config['rabbitmq']['password'], $config['rabbitmq']['virtual-host']);
-$queue_channel = $queue_connection->channel();
-
-
-publish_tex_to_pdf($logger, $queue_channel, $config['lily']['tex-to-pdf']['queue-name'], $config['lily']['tex-to-pdf']['callback-url']);
-
-
-$queue_channel->close();
-$queue_connection->close();
-$logger->warning("quit.");

+ 12 - 0
rpc/tutorials/php/morus-client.orig.json

@@ -0,0 +1,12 @@
+{
+  "server": {
+    "host": "127.0.0.1",
+    "port": 9999
+  },
+  "ssl": {
+    "ca-file": "tmp/ca.crt",
+    "key-file": "tmp/client.key",
+    "cert-file": "tmp/client.crt",
+    "authority": "www.change-me.org"
+  }
+}

+ 48 - 0
rpc/tutorials/php/morus-client.php

@@ -0,0 +1,48 @@
+<?php
+
+require dirname(__FILE__) . '/vendor/autoload.php';
+
+function markdown2html($server_uri, $options, $payload, $sanitize)
+{
+    global $logger;
+
+    $client = new Palm\Morus\V1\MarkdownClient($server_uri, $options);
+    $request = new Palm\Morus\V1\MarkdownToHtmlRequest();
+    $request->setPayload($payload);
+    $request->setSanitize($sanitize);
+    list($response, $status) = $client->ToHtml($request)->wait();
+    if ($status->code !== Grpc\STATUS_OK) {
+        $logger->error("markdown to html", ['code' => $status->code, 'details' => $status->details]);
+        exit(1);
+    }
+    $logger->info("markdown to html", ['body' => $response->getPayload()]);
+}
+
+$logger = new Monolog\Logger('palm');
+$logger->pushHandler(new Monolog\Handler\StreamHandler('php://stdout', Monolog\Level::Debug));
+
+
+if (empty($argv[1])) {
+    $logger->error("USAGE: " . $argv[0] . " CONFIG_FILE");
+    exit(1);
+}
+
+$logger->debug("load config from", ['file' => $argv[1]]);
+$config = json_decode(file_get_contents($argv[1]));
+
+$server_uri = $config->{'server'}->{'host'} . ":" . $config->{'server'}->{'port'};
+// $server_options = [
+//     'credentials' => Grpc\ChannelCredentials::createInsecure(),
+// ];
+$server_options = [
+    'credentials' => \Grpc\ChannelCredentials::createSsl(
+        file_get_contents($config->{'ssl'}->{'ca-file'}),
+        file_get_contents($config->{'ssl'}->{'key-file'}),
+        file_get_contents($config->{'ssl'}->{'cert-file'})
+    ),
+    // 'grpc.ssl_target_name_override' => $config->{'server'}->{'host'},
+    'grpc.default_authority' => $config->{'ssl'}->{'authority'}
+];
+
+$logger->info("connect to", ['server' => $server]);
+markdown2html($server_uri, $server_options, "# Hi, Palm!", true);

+ 96 - 0
rpc/tutorials/php/queue-producer.php

@@ -0,0 +1,96 @@
+<?php
+
+require dirname(__FILE__) . '/vendor/autoload.php';
+
+function texlive_task_message($s3_bucket_name)
+{
+    $output =  new Palm\Lily\V1\TeXLiveTask\Output();
+    $output->setFormat(Palm\Lily\V1\TeXLiveTask\Output\Format::Pdf);
+    $output->setBucket($s3_bucket_name);
+    $output->setObject(Ramsey\Uuid\Uuid::uuid4()->toString() . '.pdf');
+
+    $request = new Palm\Lily\V1\TeXLiveTask();
+    $request->setEntry(file_get_contents('tex/main.tex'));
+
+    foreach (array("coding.png", "foreword.tex", "section-1.tex", "section-2.tex", "postscript.tex") as $f) {
+        $request->getAttachments()[$f] = file_get_contents('tex/' . $f);
+    }
+
+    $request->setOutput($output);
+    return $request->serializeToString();
+}
+function pandoc_task_message($s3_bucket_name)
+{
+    $input =  new Palm\Lily\V1\PandocTask\Input();
+    $input->setFormat(Palm\Lily\V1\PandocTask\Format::Markdown);
+    $input->setPayload("# Hello, Lily!");
+
+    $output =  new Palm\Lily\V1\PandocTask\Output();
+    $output->setFormat(Palm\Lily\V1\PandocTask\Format::Docx);
+    $output->setBucket($s3_bucket_name);
+    $output->setObject(Ramsey\Uuid\Uuid::uuid4()->toString() . '.docx');
+
+    $request = new Palm\Lily\V1\PandocTask();
+    $request->setInput($input);
+    $request->setOutput($output);
+    return $request->serializeToString();
+}
+
+function send_message($channel, $queue_name, $message_id, $message_body)
+{
+    global $logger;
+    $logger->info("send message", ['id' => $message_id]);
+    $message = new PhpAmqpLib\Message\AMQPMessage(
+        $message_body,
+        properties: ['message_id' => $message_id, 'content_type' => 'application/grpc+proto']
+    );
+    $channel->basic_publish($message, '', $queue_name);
+}
+
+$logger = new Monolog\Logger('palm');
+$logger->pushHandler(new Monolog\Handler\StreamHandler('php://stdout', Monolog\Level::Debug));
+
+
+if (empty($argv[1]) or empty($argv[2]) or empty($argv[3])) {
+    $logger->error("USAGE: " . $argv[0] . " CONFIG_FILE JOB QUEUE");
+    exit(1);
+}
+
+$logger->debug("load config from", ['file' => $argv[1]]);
+$config = json_decode(file_get_contents($argv[1]));
+
+$logger->info("connect to", ['host' => $config->{'host'}, 'port' => $config->{'port'}, 'user' => $config->{'user'}]);
+$queue_connection = new PhpAmqpLib\Connection\AMQPStreamConnection(
+    $config->{'host'},
+    $config->{'port'},
+    $config->{'user'},
+    $config->{'password'},
+    vhost: $config->{'virtual-host'}
+);
+$queue_channel = $queue_connection->channel();
+$queue_name = $argv[3];
+$logger->info("create queue", ['name' => $queue_name]);
+$queue_channel->queue_declare($queue_name, false, false, false, false);
+
+$s3_bucket_name = "testing";
+
+foreach (range(1, 10) as $i) {
+    $message_id = Ramsey\Uuid\Uuid::uuid4()->toString();
+
+    $message_properties = [];
+    switch ($argv[2]) {
+        case "pandoc":
+            send_message($queue_channel, $queue_name, $message_id, pandoc_task_message($s3_bucket_name));
+            break;
+        case "texlive":
+            send_message($queue_channel, $queue_name, $message_id, texlive_task_message($s3_bucket_name));
+            break;
+        default:
+            $logger->error("unknown job", ['name' => $argv[2]]);
+            exit(1);
+    }
+    sleep(1);
+}
+
+$queue_channel->close();
+$queue_connection->close();

+ 7 - 0
rpc/tutorials/php/queue.orig.json

@@ -0,0 +1,7 @@
+{
+  "host": "127.0.0.1",
+  "port": 5672,
+  "user": "guest",
+  "password": "guest",
+  "virtual-host": "palm-dev"
+}

BIN
rpc/tutorials/php/tex/coding.png


+ 5 - 0
rpc/tutorials/php/tex/foreword.tex

@@ -0,0 +1,5 @@
+\frontmatter
+\chapter{Dedication}
+\chapter{Copyright}
+\chapter{Acknowledgements}
+\chapter{Preface}

+ 28 - 0
rpc/tutorials/php/tex/main.tex

@@ -0,0 +1,28 @@
+\setmainfont{DejaVu Sans}
+\setsansfont{DejaVu Sans}
+\setmonofont{DejaVu Sans Mono}
+
+\newcommand\ytl[2]{\parbox[b]{8em}{\hfill{\color{cyan}\bfseries\sffamily #1}~$\cdots\cdots$~}\makebox[0pt][c]{$\bullet$}\vrule\quad \parbox[c]{10cm}{\vspace{7pt}\color{red!40!black!80}\raggedright\sffamily #2.\\[7pt]}\\[-3pt]}
+
+\title{Tex2Pdf Testing \footnote{Not everybody could sail the ocean, but still we could share this dream.}}
+\author{通吃島主}
+\date{\today}
+
+\begin{document}
+    \maketitle
+
+    \include{foreword.tex}
+
+    \tableofcontents
+    \listoffigures
+    \listoftables
+
+    \mainmatter
+    \part{P1}
+        \chapter{C1}
+        \include{section-1.tex}
+        \include{section-2.tex}
+        
+    \include{postscript.tex}
+
+\end{document}

+ 7 - 0
rpc/tutorials/php/tex/postscript.tex

@@ -0,0 +1,7 @@
+\appendix
+\chapter{感谢}
+
+\chapter{时间线}
+
+\backmatter
+\chapter{后记}

+ 7 - 0
rpc/tutorials/php/tex/section-1.tex

@@ -0,0 +1,7 @@
+\section{Session 1}
+
+S1:
+\begin{itemize}
+    \item line 1.1
+    \item line 1.2
+\end{itemize}

+ 9 - 0
rpc/tutorials/php/tex/section-2.tex

@@ -0,0 +1,9 @@
+\section{Session 2}
+
+S2:
+
+\begin{frame}
+    \frametitle{Coding}
+    \centering
+    \includegraphics[scale=0.6]{coding.png}
+\end{frame}

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff