summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/q-and-a
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2023-11-06 03:03:43 +0000
committerNorbert Preining <norbert@preining.info>2023-11-06 03:03:43 +0000
commit240fd5fe8af67337e240c10434af4834fc86278f (patch)
treed3c79826e19d48c5559e120397514b76a28402ea /macros/latex/contrib/q-and-a
parentccd8f4d47ffbc15cb02b18cfb88cae0e995c3e69 (diff)
CTAN sync 202311060303
Diffstat (limited to 'macros/latex/contrib/q-and-a')
-rw-r--r--macros/latex/contrib/q-and-a/DEPENDS.txt1
-rw-r--r--macros/latex/contrib/q-and-a/LICENSE416
-rw-r--r--macros/latex/contrib/q-and-a/Q-and-A.cls1155
-rw-r--r--macros/latex/contrib/q-and-a/README.md61
-rw-r--r--macros/latex/contrib/q-and-a/demo/lang-fr/Q-and-A-demo-fr-content.tex92
-rw-r--r--macros/latex/contrib/q-and-a/demo/lang-fr/Q-and-A-demo-fr.pdfbin0 -> 48110 bytes
-rw-r--r--macros/latex/contrib/q-and-a/demo/lang-fr/Q-and-A-demo-fr.tex26
-rw-r--r--macros/latex/contrib/q-and-a/demo/lang-fr/code/Q-and-A-demo-fr-code-for.py2
-rw-r--r--macros/latex/contrib/q-and-a/demo/lang-fr/code/Q-and-A-demo-fr-code-func.py4
-rw-r--r--macros/latex/contrib/q-and-a/demo/lang-fr/code/Q-and-A-demo-fr-code-list.py1
-rw-r--r--macros/latex/contrib/q-and-a/demo/theme-ChatGPT/Q-and-A-demo-ChatGPT-content.tex81
-rw-r--r--macros/latex/contrib/q-and-a/demo/theme-ChatGPT/Q-and-A-demo-ChatGPT-dark.pdfbin0 -> 43260 bytes
-rw-r--r--macros/latex/contrib/q-and-a/demo/theme-ChatGPT/Q-and-A-demo-ChatGPT-light.pdfbin0 -> 43239 bytes
-rw-r--r--macros/latex/contrib/q-and-a/demo/theme-ChatGPT/Q-and-A-demo-ChatGPT.tex28
-rw-r--r--macros/latex/contrib/q-and-a/demo/theme-ChatGPT/code/Q-and-A-example-code-1.py25
-rw-r--r--macros/latex/contrib/q-and-a/demo/theme-ChatGPT/images/Q-and-A-demo-logo-ChatGPT.pdfbin0 -> 2106 bytes
-rw-r--r--macros/latex/contrib/q-and-a/demo/theme-ChatGPT/images/Q-and-A-demo-logo-User.pdfbin0 -> 1444 bytes
-rw-r--r--macros/latex/contrib/q-and-a/doc/Q-and-A-doc.pdfbin0 -> 99039 bytes
-rw-r--r--macros/latex/contrib/q-and-a/doc/Q-and-A-doc.tex269
-rw-r--r--macros/latex/contrib/q-and-a/doc/code/Q-and-A-doc-code-sample-content-result.pdfbin0 -> 21654 bytes
-rw-r--r--macros/latex/contrib/q-and-a/doc/code/Q-and-A-doc-code-sample-content-result.tex11
-rw-r--r--macros/latex/contrib/q-and-a/doc/code/Q-and-A-doc-code-sample-content.tex21
-rw-r--r--macros/latex/contrib/q-and-a/doc/code/Q-and-A-doc-code-sample-document.tex14
23 files changed, 2207 insertions, 0 deletions
diff --git a/macros/latex/contrib/q-and-a/DEPENDS.txt b/macros/latex/contrib/q-and-a/DEPENDS.txt
new file mode 100644
index 0000000000..42e7133771
--- /dev/null
+++ b/macros/latex/contrib/q-and-a/DEPENDS.txt
@@ -0,0 +1 @@
+hard einfart \ No newline at end of file
diff --git a/macros/latex/contrib/q-and-a/LICENSE b/macros/latex/contrib/q-and-a/LICENSE
new file mode 100644
index 0000000000..2244313901
--- /dev/null
+++ b/macros/latex/contrib/q-and-a/LICENSE
@@ -0,0 +1,416 @@
+The LaTeX Project Public License
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+LPPL Version 1.3c 2008-05-04
+
+Copyright 1999 2002-2008 LaTeX3 Project
+ Everyone is allowed to distribute verbatim copies of this
+ license document, but modification of it is not allowed.
+
+
+PREAMBLE
+========
+
+The LaTeX Project Public License (LPPL) is the primary license under
+which the LaTeX kernel and the base LaTeX packages are distributed.
+
+You may use this license for any work of which you hold the copyright
+and which you wish to distribute. This license may be particularly
+suitable if your work is TeX-related (such as a LaTeX package), but
+it is written in such a way that you can use it even if your work is
+unrelated to TeX.
+
+The section `WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE',
+below, gives instructions, examples, and recommendations for authors
+who are considering distributing their works under this license.
+
+This license gives conditions under which a work may be distributed
+and modified, as well as conditions under which modified versions of
+that work may be distributed.
+
+We, the LaTeX3 Project, believe that the conditions below give you
+the freedom to make and distribute modified versions of your work
+that conform with whatever technical specifications you wish while
+maintaining the availability, integrity, and reliability of
+that work. If you do not see how to achieve your goal while
+meeting these conditions, then read the document `cfgguide.tex'
+and `modguide.tex' in the base LaTeX distribution for suggestions.
+
+
+DEFINITIONS
+===========
+
+In this license document the following terms are used:
+
+ `Work'
+ Any work being distributed under this License.
+
+ `Derived Work'
+ Any work that under any applicable law is derived from the Work.
+
+ `Modification'
+ Any procedure that produces a Derived Work under any applicable
+ law -- for example, the production of a file containing an
+ original file associated with the Work or a significant portion of
+ such a file, either verbatim or with modifications and/or
+ translated into another language.
+
+ `Modify'
+ To apply any procedure that produces a Derived Work under any
+ applicable law.
+
+ `Distribution'
+ Making copies of the Work available from one person to another, in
+ whole or in part. Distribution includes (but is not limited to)
+ making any electronic components of the Work accessible by
+ file transfer protocols such as FTP or HTTP or by shared file
+ systems such as Sun's Network File System (NFS).
+
+ `Compiled Work'
+ A version of the Work that has been processed into a form where it
+ is directly usable on a computer system. This processing may
+ include using installation facilities provided by the Work,
+ transformations of the Work, copying of components of the Work, or
+ other activities. Note that modification of any installation
+ facilities provided by the Work constitutes modification of the Work.
+
+ `Current Maintainer'
+ A person or persons nominated as such within the Work. If there is
+ no such explicit nomination then it is the `Copyright Holder' under
+ any applicable law.
+
+ `Base Interpreter'
+ A program or process that is normally needed for running or
+ interpreting a part or the whole of the Work.
+
+ A Base Interpreter may depend on external components but these
+ are not considered part of the Base Interpreter provided that each
+ external component clearly identifies itself whenever it is used
+ interactively. Unless explicitly specified when applying the
+ license to the Work, the only applicable Base Interpreter is a
+ `LaTeX-Format' or in the case of files belonging to the
+ `LaTeX-format' a program implementing the `TeX language'.
+
+
+
+CONDITIONS ON DISTRIBUTION AND MODIFICATION
+===========================================
+
+1. Activities other than distribution and/or modification of the Work
+are not covered by this license; they are outside its scope. In
+particular, the act of running the Work is not restricted and no
+requirements are made concerning any offers of support for the Work.
+
+2. You may distribute a complete, unmodified copy of the Work as you
+received it. Distribution of only part of the Work is considered
+modification of the Work, and no right to distribute such a Derived
+Work may be assumed under the terms of this clause.
+
+3. You may distribute a Compiled Work that has been generated from a
+complete, unmodified copy of the Work as distributed under Clause 2
+above, as long as that Compiled Work is distributed in such a way that
+the recipients may install the Compiled Work on their system exactly
+as it would have been installed if they generated a Compiled Work
+directly from the Work.
+
+4. If you are the Current Maintainer of the Work, you may, without
+restriction, modify the Work, thus creating a Derived Work. You may
+also distribute the Derived Work without restriction, including
+Compiled Works generated from the Derived Work. Derived Works
+distributed in this manner by the Current Maintainer are considered to
+be updated versions of the Work.
+
+5. If you are not the Current Maintainer of the Work, you may modify
+your copy of the Work, thus creating a Derived Work based on the Work,
+and compile this Derived Work, thus creating a Compiled Work based on
+the Derived Work.
+
+6. If you are not the Current Maintainer of the Work, you may
+distribute a Derived Work provided the following conditions are met
+for every component of the Work unless that component clearly states
+in the copyright notice that it is exempt from that condition. Only
+the Current Maintainer is allowed to add such statements of exemption
+to a component of the Work.
+
+ a. If a component of this Derived Work can be a direct replacement
+ for a component of the Work when that component is used with the
+ Base Interpreter, then, wherever this component of the Work
+ identifies itself to the user when used interactively with that
+ Base Interpreter, the replacement component of this Derived Work
+ clearly and unambiguously identifies itself as a modified version
+ of this component to the user when used interactively with that
+ Base Interpreter.
+
+ b. Every component of the Derived Work contains prominent notices
+ detailing the nature of the changes to that component, or a
+ prominent reference to another file that is distributed as part
+ of the Derived Work and that contains a complete and accurate log
+ of the changes.
+
+ c. No information in the Derived Work implies that any persons,
+ including (but not limited to) the authors of the original version
+ of the Work, provide any support, including (but not limited to)
+ the reporting and handling of errors, to recipients of the
+ Derived Work unless those persons have stated explicitly that
+ they do provide such support for the Derived Work.
+
+ d. You distribute at least one of the following with the Derived Work:
+
+ 1. A complete, unmodified copy of the Work;
+ if your distribution of a modified component is made by
+ offering access to copy the modified component from a
+ designated place, then offering equivalent access to copy
+ the Work from the same or some similar place meets this
+ condition, even though third parties are not compelled to
+ copy the Work along with the modified component;
+
+ 2. Information that is sufficient to obtain a complete,
+ unmodified copy of the Work.
+
+7. If you are not the Current Maintainer of the Work, you may
+distribute a Compiled Work generated from a Derived Work, as long as
+the Derived Work is distributed to all recipients of the Compiled
+Work, and as long as the conditions of Clause 6, above, are met with
+regard to the Derived Work.
+
+8. The conditions above are not intended to prohibit, and hence do not
+apply to, the modification, by any method, of any component so that it
+becomes identical to an updated version of that component of the Work as
+it is distributed by the Current Maintainer under Clause 4, above.
+
+9. Distribution of the Work or any Derived Work in an alternative
+format, where the Work or that Derived Work (in whole or in part) is
+then produced by applying some process to that format, does not relax or
+nullify any sections of this license as they pertain to the results of
+applying that process.
+
+10. a. A Derived Work may be distributed under a different license
+ provided that license itself honors the conditions listed in
+ Clause 6 above, in regard to the Work, though it does not have
+ to honor the rest of the conditions in this license.
+
+ b. If a Derived Work is distributed under a different license, that
+ Derived Work must provide sufficient documentation as part of
+ itself to allow each recipient of that Derived Work to honor the
+ restrictions in Clause 6 above, concerning changes from the Work.
+
+11. This license places no restrictions on works that are unrelated to
+the Work, nor does this license place any restrictions on aggregating
+such works with the Work by any means.
+
+12. Nothing in this license is intended to, or may be used to, prevent
+complete compliance by all parties with all applicable laws.
+
+
+NO WARRANTY
+===========
+
+There is no warranty for the Work. Except when otherwise stated in
+writing, the Copyright Holder provides the Work `as is', without
+warranty of any kind, either expressed or implied, including, but not
+limited to, the implied warranties of merchantability and fitness for a
+particular purpose. The entire risk as to the quality and performance
+of the Work is with you. Should the Work prove defective, you assume
+the cost of all necessary servicing, repair, or correction.
+
+In no event unless required by applicable law or agreed to in writing
+will The Copyright Holder, or any author named in the components of the
+Work, or any other party who may distribute and/or modify the Work as
+permitted above, be liable to you for damages, including any general,
+special, incidental or consequential damages arising out of any use of
+the Work or out of inability to use the Work (including, but not limited
+to, loss of data, data being rendered inaccurate, or losses sustained by
+anyone as a result of any failure of the Work to operate with any other
+programs), even if the Copyright Holder or said author or said other
+party has been advised of the possibility of such damages.
+
+
+MAINTENANCE OF THE WORK
+=======================
+
+The Work has the status `author-maintained' if the Copyright Holder
+explicitly and prominently states near the primary copyright notice in
+the Work that the Work can only be maintained by the Copyright Holder
+or simply that it is `author-maintained'.
+
+The Work has the status `maintained' if there is a Current Maintainer
+who has indicated in the Work that they are willing to receive error
+reports for the Work (for example, by supplying a valid e-mail
+address). It is not required for the Current Maintainer to acknowledge
+or act upon these error reports.
+
+The Work changes from status `maintained' to `unmaintained' if there
+is no Current Maintainer, or the person stated to be Current
+Maintainer of the work cannot be reached through the indicated means
+of communication for a period of six months, and there are no other
+significant signs of active maintenance.
+
+You can become the Current Maintainer of the Work by agreement with
+any existing Current Maintainer to take over this role.
+
+If the Work is unmaintained, you can become the Current Maintainer of
+the Work through the following steps:
+
+ 1. Make a reasonable attempt to trace the Current Maintainer (and
+ the Copyright Holder, if the two differ) through the means of
+ an Internet or similar search.
+
+ 2. If this search is successful, then enquire whether the Work
+ is still maintained.
+
+ a. If it is being maintained, then ask the Current Maintainer
+ to update their communication data within one month.
+
+ b. If the search is unsuccessful or no action to resume active
+ maintenance is taken by the Current Maintainer, then announce
+ within the pertinent community your intention to take over
+ maintenance. (If the Work is a LaTeX work, this could be
+ done, for example, by posting to comp.text.tex.)
+
+ 3a. If the Current Maintainer is reachable and agrees to pass
+ maintenance of the Work to you, then this takes effect
+ immediately upon announcement.
+
+ b. If the Current Maintainer is not reachable and the Copyright
+ Holder agrees that maintenance of the Work be passed to you,
+ then this takes effect immediately upon announcement.
+
+ 4. If you make an `intention announcement' as described in 2b. above
+ and after three months your intention is challenged neither by
+ the Current Maintainer nor by the Copyright Holder nor by other
+ people, then you may arrange for the Work to be changed so as
+ to name you as the (new) Current Maintainer.
+
+ 5. If the previously unreachable Current Maintainer becomes
+ reachable once more within three months of a change completed
+ under the terms of 3b) or 4), then that Current Maintainer must
+ become or remain the Current Maintainer upon request provided
+ they then update their communication data within one month.
+
+A change in the Current Maintainer does not, of itself, alter the fact
+that the Work is distributed under the LPPL license.
+
+If you become the Current Maintainer of the Work, you should
+immediately provide, within the Work, a prominent and unambiguous
+statement of your status as Current Maintainer. You should also
+announce your new status to the same pertinent community as
+in 2b) above.
+
+
+WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE
+======================================================
+
+This section contains important instructions, examples, and
+recommendations for authors who are considering distributing their
+works under this license. These authors are addressed as `you' in
+this section.
+
+Choosing This License or Another License
+----------------------------------------
+
+If for any part of your work you want or need to use *distribution*
+conditions that differ significantly from those in this license, then
+do not refer to this license anywhere in your work but, instead,
+distribute your work under a different license. You may use the text
+of this license as a model for your own license, but your license
+should not refer to the LPPL or otherwise give the impression that
+your work is distributed under the LPPL.
+
+The document `modguide.tex' in the base LaTeX distribution explains
+the motivation behind the conditions of this license. It explains,
+for example, why distributing LaTeX under the GNU General Public
+License (GPL) was considered inappropriate. Even if your work is
+unrelated to LaTeX, the discussion in `modguide.tex' may still be
+relevant, and authors intending to distribute their works under any
+license are encouraged to read it.
+
+A Recommendation on Modification Without Distribution
+-----------------------------------------------------
+
+It is wise never to modify a component of the Work, even for your own
+personal use, without also meeting the above conditions for
+distributing the modified component. While you might intend that such
+modifications will never be distributed, often this will happen by
+accident -- you may forget that you have modified that component; or
+it may not occur to you when allowing others to access the modified
+version that you are thus distributing it and violating the conditions
+of this license in ways that could have legal implications and, worse,
+cause problems for the community. It is therefore usually in your
+best interest to keep your copy of the Work identical with the public
+one. Many works provide ways to control the behavior of that work
+without altering any of its licensed components.
+
+How to Use This License
+-----------------------
+
+To use this license, place in each of the components of your work both
+an explicit copyright notice including your name and the year the work
+was authored and/or last substantially modified. Include also a
+statement that the distribution and/or modification of that
+component is constrained by the conditions in this license.
+
+Here is an example of such a notice and statement:
+
+ %% pig.dtx
+ %% Copyright 2005 M. Y. Name
+ %
+ % This work may be distributed and/or modified under the
+ % conditions of the LaTeX Project Public License, either version 1.3
+ % of this license or (at your option) any later version.
+ % The latest version of this license is in
+ % http://www.latex-project.org/lppl.txt
+ % and version 1.3 or later is part of all distributions of LaTeX
+ % version 2005/12/01 or later.
+ %
+ % This work has the LPPL maintenance status `maintained'.
+ %
+ % The Current Maintainer of this work is M. Y. Name.
+ %
+ % This work consists of the files pig.dtx and pig.ins
+ % and the derived file pig.sty.
+
+Given such a notice and statement in a file, the conditions
+given in this license document would apply, with the `Work' referring
+to the three files `pig.dtx', `pig.ins', and `pig.sty' (the last being
+generated from `pig.dtx' using `pig.ins'), the `Base Interpreter'
+referring to any `LaTeX-Format', and both `Copyright Holder' and
+`Current Maintainer' referring to the person `M. Y. Name'.
+
+If you do not want the Maintenance section of LPPL to apply to your
+Work, change `maintained' above into `author-maintained'.
+However, we recommend that you use `maintained', as the Maintenance
+section was added in order to ensure that your Work remains useful to
+the community even when you can no longer maintain and support it
+yourself.
+
+Derived Works That Are Not Replacements
+---------------------------------------
+
+Several clauses of the LPPL specify means to provide reliability and
+stability for the user community. They therefore concern themselves
+with the case that a Derived Work is intended to be used as a
+(compatible or incompatible) replacement of the original Work. If
+this is not the case (e.g., if a few lines of code are reused for a
+completely different task), then clauses 6b and 6d shall not apply.
+
+
+Important Recommendations
+-------------------------
+
+ Defining What Constitutes the Work
+
+ The LPPL requires that distributions of the Work contain all the
+ files of the Work. It is therefore important that you provide a
+ way for the licensee to determine which files constitute the Work.
+ This could, for example, be achieved by explicitly listing all the
+ files of the Work near the copyright notice of each file or by
+ using a line such as:
+
+ % This work consists of all files listed in manifest.txt.
+
+ in that place. In the absence of an unequivocal list it might be
+ impossible for the licensee to determine what is considered by you
+ to comprise the Work and, in such a case, the licensee would be
+ entitled to make reasonable conjectures as to which files comprise
+ the Work.
+
diff --git a/macros/latex/contrib/q-and-a/Q-and-A.cls b/macros/latex/contrib/q-and-a/Q-and-A.cls
new file mode 100644
index 0000000000..20078cb62a
--- /dev/null
+++ b/macros/latex/contrib/q-and-a/Q-and-A.cls
@@ -0,0 +1,1155 @@
+%%
+%% Copyright (C) 2023 by Jinwen XU
+%% -------------------------------
+%%
+%% This file may be distributed and/or modified under the conditions of
+%% the LaTeX Project Public License, either version 1.3c of this license
+%% or (at your option) any later version. The latest version of this
+%% license is in:
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+\NeedsTeXFormat{LaTeX2e}[2022-06-01]
+\ProvidesExplClass
+ {Q-and-A}
+ {2023/11/05} {}
+ {Document class for typesetting Q&A conversation}
+
+\keys_define:nn { Q-and-A }
+ {
+ , scroll .bool_set:N = \l__QA_scroll_bool
+ , scroll .initial:n = { false }
+
+ , theme .str_set:N = \l__QA_theme_str
+ , theme .initial:n = { default }
+ , use-theme .str_set:N = \l__QA_theme_str
+ , use~theme .str_set:N = \l__QA_theme_str
+ , use theme .str_set:N = \l__QA_theme_str
+ , ChatGPT .meta:n = { theme = ChatGPT-light }
+ , ChatGPT-light .meta:n = { theme = ChatGPT-light }
+ , ChatGPT~light .meta:n = { theme = ChatGPT-light }
+ , ChatGPT light .meta:n = { theme = ChatGPT-light }
+ , ChatGPT-dark .meta:n = { theme = ChatGPT-dark }
+ , ChatGPT~dark .meta:n = { theme = ChatGPT-dark }
+ , ChatGPT dark .meta:n = { theme = ChatGPT-dark }
+
+ , answer-outside-the-box .bool_set:N = \l__QA_answer_outside_the_box_bool
+ , answer-outside-the-box .initial:n = { false }
+ , answer~outside~the~box .bool_set:N = \l__QA_answer_outside_the_box_bool
+ , answer outside the box .bool_set:N = \l__QA_answer_outside_the_box_bool
+ , answer-outside-box .bool_set:N = \l__QA_answer_outside_the_box_bool
+ , answer~outside~box .bool_set:N = \l__QA_answer_outside_the_box_bool
+ , answer outside box .bool_set:N = \l__QA_answer_outside_the_box_bool
+ , answer-out-of-the-box .bool_set:N = \l__QA_answer_outside_the_box_bool
+ , answer~out~of~the~box .bool_set:N = \l__QA_answer_outside_the_box_bool
+ , answer out of the box .bool_set:N = \l__QA_answer_outside_the_box_bool
+ , answer-out-of-box .bool_set:N = \l__QA_answer_outside_the_box_bool
+ , answer~out~of~box .bool_set:N = \l__QA_answer_outside_the_box_bool
+ , answer out of box .bool_set:N = \l__QA_answer_outside_the_box_bool
+
+ , unknown .code:n = {
+ \PassOptionsToClass { \CurrentOption } { minimart }
+ \PassOptionsToClass { \CurrentOption } { einfart }
+ \PassOptionsToPackage { \CurrentOption } { ProjLib }
+ }
+ }
+\ProcessKeyOptions [ Q-and-A ]
+
+\sys_if_engine_pdftex:TF
+ {
+ \PassOptionsToClass { use indent = false } { minimart }
+ \LoadClass { minimart }
+ }
+ {
+ \PassOptionsToClass { use indent = false } { einfart }
+ \LoadClass { einfart }
+ }
+
+\RequirePackage { ProjLib }
+
+\colorlet{QA-Q-back}{.!3}
+\colorlet{QA-Q-text}{.}
+\colorlet{QA-Q-emph}{.}
+\colorlet{QA-A-back}{.!0}
+\colorlet{QA-A-text}{.}
+\colorlet{QA-A-emph}{.}
+\colorlet{QA-N-back}{.!0}
+\colorlet{QA-N-text}{.}
+\colorlet{QA-N-emph}{.}
+
+\definecolor{QA-code-back}{RGB}{ 0, 0, 0}
+\definecolor{QA-code-text}{RGB}{255,255,255}
+\definecolor{QA-code-title-back}{RGB}{ 52, 53, 65}
+\definecolor{QA-code-title-text}{RGB}{217,217,227}
+
+\colorlet{QA-sep-line}{.!27!paper}
+
+\colorlet{paper}{QA-A-back}
+\colorlet{main-text}{QA-A-text}
+\colorlet{emph-text}{QA-A-emph}
+
+\str_if_eq:onT { \l__QA_theme_str } { ChatGPT-dark }
+ {
+ \definecolor{QA-Q-back}{RGB}{ 52, 53, 65}
+ \definecolor{QA-Q-text}{RGB}{236,236,241}
+ \definecolor{QA-Q-emph}{RGB}{255,255,255}
+ \definecolor{QA-A-back}{RGB}{ 68, 70, 84}
+ \definecolor{QA-A-text}{RGB}{209,213,219}
+ \definecolor{QA-A-emph}{RGB}{255,255,255}
+ \colorlet{QA-N-back}{QA-Q-back}
+ \colorlet{QA-N-text}{QA-Q-text}
+ \colorlet{paper}{QA-Q-back}
+ \colorlet{main-text}{QA-Q-text}
+ \colorlet{emph-text}{QA-Q-text}
+ }
+
+\str_if_eq:onT { \l__QA_theme_str } { ChatGPT-light }
+ {
+ \definecolor{QA-Q-back}{RGB}{255,255,255}
+ \definecolor{QA-Q-text}{RGB}{ 52, 53, 65}
+ \definecolor{QA-Q-emph}{RGB}{ 0, 0, 0}
+ \definecolor{QA-A-back}{RGB}{247,247,248}
+ \definecolor{QA-A-text}{RGB}{ 55, 65, 81}
+ \definecolor{QA-A-emph}{RGB}{ 0, 0, 0}
+ \colorlet{QA-N-back}{QA-Q-back}
+ \colorlet{QA-N-text}{QA-Q-text}
+ \colorlet{paper}{QA-Q-back}
+ \colorlet{main-text}{QA-Q-text}
+ \colorlet{emph-text}{QA-Q-text}
+ }
+
+\projlib_paper_set_page_color:n { paper }
+\projlib_paper_set_text_color:n { main-text }
+
+\projlib_langauge_define_multilingual_text:Nn \l_QA_continued_text_tl
+ {
+ , EN = (continued)
+ , FR = (suite~de~la~page~précédente)
+ , DE = (Fortsetzung~von~der~vorherigen~Seite)
+ , IT = (continua~dalla~pagina~precedente)
+ , PT = (continuação~da~página~anterior)
+ , BR = (continuação~da~página~anterior)
+ , ES = (continúa~de~la~página~anterior)
+ , CN = (接前页)
+ , TC = (接前頁)
+ , JP = (前頁から続き)
+ , RU = (продолжение~с~предыдущей~страницы)
+ }
+
+\RequirePackage { enumitem }
+
+\dim_new:N \l_QA_item_indentation_dim
+\dim_set:Nn \l_QA_item_indentation_dim { 1.5em }
+\dim_new:N \l_QA_list_indentation_dim
+\dim_set:Nn \l_QA_list_indentation_dim { 3em }
+\dim_new:N \l_QA_list_labelsep_dim
+\dim_set:Nn \l_QA_list_labelsep_dim { 1em }
+
+\exp_args:No \str_if_in:nnT { \l__QA_theme_str } { ChatGPT }
+ {
+ \dim_set:Nn \l_QA_item_indentation_dim { .33em }
+ \dim_set:Nn \l_QA_list_indentation_dim { 4.5em }
+ \dim_set:Nn \l_QA_list_labelsep_dim { 1.5em }
+ }
+
+\newlist { QA-entry } { description } { 1 }
+\setlist [ QA-entry ] { font = \normalfont\sffamily, leftmargin = \l_QA_list_indentation_dim, labelsep = \l_QA_list_labelsep_dim, labelwidth=!, parsep=\parskip }
+\renewcommand{\descriptionlabel}[1]{#1}
+
+\bool_new:N \l__QA_inside_list_bool
+\bool_set_false:N \l__QA_inside_list_bool
+\hook_gput_code:nnn { env/enumerate/begin } { QA }
+ { \bool_set_true:N \l__QA_inside_list_bool }
+% \hook_gput_code:nnn { env/QA-em-itemize/begin } { QA }
+% { \bool_set_true:N \l__QA_inside_list_bool }
+
+\tl_new:N \l__QA_item_indentation_tl
+\tl_set:Nn \l__QA_item_indentation_tl
+ {
+ \bool_if:NTF \l__QA_inside_list_bool
+ { 1.5em }
+ { \l_QA_item_indentation_dim }
+ }
+
+\newlist { QA-em-itemize } { itemize } { 1 }
+\setlist[QA-em-itemize,1]{
+ leftmargin= \l__QA_item_indentation_tl, labelwidth=1em,
+ label=\textcolor{.!27!paper}{\raisebox{.12em}{\scriptsize$\bullet$}}}
+% \setlist[QA-em-itemize,1]{
+% leftmargin= \l_QA_item_indentation_dim, labelwidth=1em,
+% label=\textcolor{.!27!paper}{$\bullet$}}
+
+% The following line is mainly for the scroll mode
+\setlist[itemize]{
+ leftmargin= \l__QA_item_indentation_tl, labelwidth=1em,
+ label=\textcolor{.!27!paper}{\raisebox{.12em}{\scriptsize$\bullet$}}}
+\AddLanguageSetting
+ {
+ \setlist[itemize,1]{
+ leftmargin= \l__QA_item_indentation_tl, labelwidth=1em,
+ label=\textcolor{.!27!paper}{\raisebox{.12em}{\scriptsize$\bullet$}}}
+ \setlist[itemize,2]{
+ leftmargin= 1.5em,
+ label=\textcolor{.!27!paper}{\rule[.2\baselineskip]{.55em}{.75pt}}}
+ \setlist[itemize,3]{leftmargin=*,label=\textcolor{.!27!paper}{$\circ$}}
+ \setlist[itemize,4]{leftmargin=*,label=\textcolor{.!27!paper}{$\ast$}}
+ }
+\AddLanguageSetting [ FR ]
+ {
+ \setlist[itemize,1]{%leftmargin=\maxof{\parindent}{1.5em},
+ leftmargin= \l__QA_item_indentation_tl, labelwidth=1em,
+ label=\textcolor{.!39!paper}{\rule[.2\baselineskip]{.8em}{.75pt}}}
+ }
+\AddLanguageSetting [ ES ]
+ {
+ \setlist[itemize,1]{%leftmargin=\maxof{\parindent}{1.5em},
+ leftmargin= \l__QA_item_indentation_tl, labelwidth=1em,
+ label=\textcolor{.!27!paper}{
+ \leavevmode\hbox to 1.2ex{\hss\vrule height .9ex width .7ex depth -.2ex\hss}
+ }}
+ }
+
+\setlist[enumerate,1]{label = \color{.!55!paper}\arabic*.,
+ ref = \color{.!55!paper}\arabic*,
+ leftmargin= \l_QA_item_indentation_dim }
+\setlist[enumerate,2]{label = \color{.!55!paper}\roman*.,
+ ref = \color{.!55!paper}\arabic{enumi}.\roman*}
+\setlist[enumerate,3]{label = \color{.!55!paper}\emph{\alph*}.,
+ ref = \color{.!55!paper}\arabic{enumi}.\roman{enumii}.\emph{\alph*}}
+
+\dim_new:N \l_QA_labelsep_dim
+\dim_set:Nn \l_QA_labelsep_dim { \labelsep }
+\setlist [ 2 ] { labelsep = \l_QA_labelsep_dim, labelwidth = !}
+
+\PassOptionsToPackage { many } { tcolorbox }
+\RequirePackage { tcolorbox }
+\ExplSyntaxOff
+\tcbuselibrary{listings}
+\ExplSyntaxOn
+
+\tcbset{QA-common/.style={
+ enhanced,
+ breakable, height~fixed~for=first~and~middle,
+ enlargepage~flexible=\baselineskip,
+ title~after~break={\l_QA_continued_text_tl},
+ center~title,
+ titlerule=-1pt,
+ toptitle=1mm,
+ bottomtitle=-2mm,
+ parbox=false,
+ spread~sidewards=1mm,
+ before={\vspace{-1mm}},
+ after={\vspace{-1mm}},
+ sharp~corners,
+ frame~hidden,
+ top=1em,
+ bottom=1em,
+ left=1em,
+ right=4em,
+ }
+}
+
+\tcbset{QA-additional/.style={}}
+% ChatGPT style
+\exp_args:No \str_if_in:nnT { \l__QA_theme_str } { ChatGPT }
+ {
+ \tcbset{QA-additional/.style={
+ fontupper=\sffamily,
+ code={\onehalfspacing},
+ top=2em,
+ bottom=2em,
+ }
+ }
+ }
+
+\definecolor{QA-code-keyword}{RGB}{ 47,148,210}
+\definecolor{QA-code-comment}{RGB}{128,128,128}
+\definecolor{QA-code-string }{RGB}{ 5,165,126}
+\lstalias[]{code}[LaTeX]{tex}
+\lstalias[]{latex}[LaTeX]{tex}
+% \lstloadlanguages{[LaTeX]TeX}
+\lstset{
+ basicstyle = \small\normalfont\ttfamily,
+ keywordstyle = \color{QA-code-keyword},
+ commentstyle = \color{QA-code-comment},
+ stringstyle = \color{QA-code-string},
+ showstringspaces = false,
+}
+
+% Based on https://tex.stackexchange.com/a/117848
+\NewDocumentCommand \QAaddmoretexcs { O{common} m m }
+ {%
+ \lowercase{\@ifundefined{lstlang@tex$#1}}{%
+ \lstloadlanguages{[#1]TeX}%
+ }{}%
+ \lowercase{\expandafter\g@addto@macro\csname lstlang@tex$#1\endcsname}{%
+ \lstset{
+ classoffset = 0,
+ texcsstyle =* \color{QA-code-keyword},
+ moretexcs = {#2}, % LaTeX2 commands
+ classoffset = 1,
+ texcsstyle =* \color{cyan},
+ alsoletter = {_,:},
+ moretexcs = {#3}, % LaTeX3 commands
+ classoffset = 0,
+ escapeinside = {(@@@}{)}, % https://tex.stackexchange.com/q/493753
+ }%
+ }%
+ }
+
+% Common commands
+\QAaddmoretexcs [LaTeX]
+ {% LaTeX2 commands
+ ExplSyntaxOn,ExplSyntaxOff,
+ NewDocumentCommand,NewDocumentEnvironment,
+ includegraphics,
+ definecolor, colorlet, color, textcolor,
+ }
+ {% LaTeX3 commands
+ }
+% Custom commands
+\QAaddmoretexcs [LaTeX]
+ {% LaTeX2 commands
+ UseLanguage,
+ TheDate,
+ SetLogoCode,
+ }
+ {% LaTeX3 commands
+ }
+
+\NewTCBInputListing \QAInsertCode { O{code} O{} m }
+ {
+ enhanced, grow~sidewards~by=1mm,
+ enforce~breakable, height~fixed~for=first~and~middle,
+ enlargepage~flexible=\baselineskip,
+ listing~only,
+ fonttitle=\scriptsize\normalfont\sffamily,
+ listing~options={
+ language = #1,
+ breaklines = true,
+ breakindent = 0pt,
+ % breakatwhitespace = true,
+ },
+ toptitle=1mm,
+ bottomtitle=1mm,
+ titlerule=-1pt,
+ frame~hidden,
+ colback=QA-code-back,
+ colupper=QA-code-text,
+ colbacktitle=QA-code-title-back,
+ coltitle=QA-code-title-text,
+ left=.75em,
+ right=.75em,
+ #2,
+ title={#1},
+ listing~file={#3},
+ }
+
+\tl_new:N \g_QA_content_tl
+\NewDocumentEnvironment { Q-and-A } { +b }
+ {
+ \tl_gset:Nn \g_QA_content_tl { #1 }
+ \QA_parse_content:N \g_QA_content_tl
+ \tl_use:N \g_QA_content_tl
+ }
+ { }
+\tl_new:N \g_QA_local_content_tl
+\NewDocumentCommand \QAtext { +m }
+ {
+ \group_begin:
+ \tl_gset:Nn \g_QA_local_content_tl { #1 }
+ \QA_parse_content:N \g_QA_local_content_tl
+ \tl_use:N \g_QA_local_content_tl
+ \group_end:
+ }
+
+\NewDocumentCommand \QAInput { m }
+ {
+ \file_get:nnN { #1 } { } \l_tmpa_tl
+ \exp_args:No \QAtext { \l_tmpa_tl }
+ % Currently, for some reason, the following adjustment is needed
+ \vspace{-2\parskip}
+ }
+\NewDocumentCommand \QAInclude { m }
+ {
+ \clearpage
+ \QAInput { #1 }
+ \clearpage
+ }
+
+\NewDocumentCommand \QAEmph { m }
+ {
+ \textcolor{emph-text}{\textbf{ #1 }}
+ }
+
+\def \QAadjustitem { \vspace{0pt} }
+\NewDocumentCommand \QAItem { m m }
+ {
+ \tl_if_blank:nTF { #1 }
+ {
+ \begin{itemize}
+ \item #2
+ \end{itemize}
+ }
+ {
+ \bool_if:NTF \l__QA_inside_list_bool
+ {
+ \begin{itemize}
+ \item \QAEmph{ \ignorespaces #1 : } ~ \ignorespaces #2
+ \end{itemize}
+ }
+ {
+ \begin{QA-em-itemize}
+ \bool_set_true:N \l__QA_inside_list_bool
+ \item \QAEmph{ \ignorespaces #1 : } ~ \ignorespaces #2
+ \end{QA-em-itemize}
+ % \bool_set_true:N \l__QA_inside_list_bool
+ }
+ }
+ }
+\NewDocumentCommand \QAEnum { s m m }
+ {
+ \tl_if_blank:nTF { #1 }
+ {
+ \tl_set:Nn \l_tmpa_tl { }
+ }
+ {
+ \tl_set:Nn \l_tmpa_tl { \QAEmph{ #2 : } ~ }
+ }
+ \bool_if:NTF #1
+ {
+ \begin{enumerate}
+ \item \l_tmpa_tl \ignorespaces #3
+ \end{enumerate}
+ }
+ {
+ \begin{enumerate}[resume]
+ \item \l_tmpa_tl \ignorespaces #3
+ \end{enumerate}
+ }
+ }
+
+\NewDocumentCommand \QANote { m }
+ {
+ \dim_set:Nn \l_tmpa_dim { \labelsep }
+ \begin{tcolorbox}[enhanced~jigsaw, breakable,
+ frame~hidden,
+ interior~hidden,
+ boxrule=0pt,
+ grow~to~left~by=-.75mm,
+ before~skip=1mm,
+ after~skip=1mm,
+ top=-.75mm, bottom=-.75mm, left=.33em, right=-1mm,
+ borderline~west={.2em}{0pt}{QA-N-text!17!QA-N-back},
+ ]
+ #1
+ \end{tcolorbox}
+ \vspace{.15\baselineskip}
+ \dim_gset:Nn \labelsep { \l_tmpa_dim }
+ }
+
+\newenvironment{QACompactCenter}
+ {\parskip=0pt\par\nopagebreak\centering}
+ {\par\noindent\ignorespacesafterend}
+\newenvironment{QACenter}
+ {\parskip=0pt\par\medskip\nopagebreak\centering}
+ {\par\noindent\ignorespacesafterend}
+\newenvironment{QALeft}
+ {\parskip=0pt\par\medskip\nopagebreak\raggedright}
+ {\par\noindent\ignorespacesafterend}
+\newenvironment{QARight}
+ {\parskip=0pt\par\medskip\nopagebreak\raggedleft}
+ {\par\noindent\ignorespacesafterend}
+\NewDocumentCommand \QACompactCenterText { m }
+ {
+ \begin{QACompactCenter}
+ #1
+ \end{QACompactCenter}
+ }
+\NewDocumentCommand \QAShowImageCenter { D<>{*} m D<>{*} }
+ {
+ \str_if_eq:nnTF { #1 } { * }
+ {
+ \str_if_eq:nnTF { #3 } { * }
+ {
+ \tl_set:Nn \l_tmpa_tl { 1 }
+ }
+ {
+ \tl_set:Nn \l_tmpa_tl { #3 }
+ }
+ }
+ {
+ \tl_set:Nn \l_tmpa_tl { #1 }
+ }
+ \begin{QACenter}
+ \includegraphics[width= \tl_use:N \l_tmpa_tl \linewidth]{#2}
+ \end{QACenter}
+ }
+\NewDocumentCommand \QAShowImageLeft { D<>{*} m D<>{*} }
+ {
+ \str_if_eq:nnTF { #1 } { * }
+ {
+ \str_if_eq:nnTF { #3 } { * }
+ {
+ \tl_set:Nn \l_tmpa_tl { 1 }
+ }
+ {
+ \tl_set:Nn \l_tmpa_tl { #3 }
+ }
+ }
+ {
+ \tl_set:Nn \l_tmpa_tl { #1 }
+ }
+ \begin{QALeft}
+ \includegraphics[width= \tl_use:N \l_tmpa_tl \linewidth]{#2}
+ \end{QALeft}
+ }
+\NewDocumentCommand \QAShowImageRight { D<>{*} m D<>{*} }
+ {
+ \str_if_eq:nnTF { #1 } { * }
+ {
+ \str_if_eq:nnTF { #3 } { * }
+ {
+ \tl_set:Nn \l_tmpa_tl { 1 }
+ }
+ {
+ \tl_set:Nn \l_tmpa_tl { #3 }
+ }
+ }
+ {
+ \tl_set:Nn \l_tmpa_tl { #1 }
+ }
+ \begin{QARight}
+ \includegraphics[width= \tl_use:N \l_tmpa_tl \linewidth]{#2}
+ \end{QARight}
+ }
+
+\newtcbox \QACodebox
+ {
+ tcbox~raise~base,
+ nobeforeafter,
+ boxrule=.1pt, boxsep=1.5pt, arc=1pt,
+ left=.5pt, right=.5pt, top=0pt, bottom=0pt,
+ colframe=main-text!60!paper,
+ colback=main-text!3!paper,
+ % colupper=emph-text,
+ fontupper=\small\normalfont\ttfamily,
+ }
+\NewDocumentCommand \QACode { m }
+ {
+ % \textcolor{emph-text}{\texttt{#1}}
+ \QACodebox{\vphantom{Äpgjy}#1}
+ }
+\exp_args:No \str_if_in:nnT { \l__QA_theme_str } { ChatGPT }
+ {
+ \RenewDocumentCommand \QACode { m }
+ {
+ \textcolor{emph-text}{\bfseries
+ % {\hskip.6ex\`{}\hskip-.15ex}
+ \raisebox{-.15em}{\hskip.6ex\larger\`{}\hskip-.15ex}
+ % \raisebox{-.25em}{\hskip.6ex\larger[2]\`{}\hskip-.15ex}
+ \texttt{ #1 }
+ % {\hskip.6ex\`{}\hskip-.15ex}
+ \raisebox{-.15em}{\hskip.6ex\larger\`{}\hskip-.15ex}
+ % \raisebox{-.25em}{\hskip.6ex\larger[2]\`{}\hskip-.15ex}
+ }
+ }
+ }
+
+\NewDocumentCommand \QASepLine { O{.75pt} }
+ {
+ \par
+ \vspace*{-.5\baselineskip}
+ \noindent
+ \hspace*{-\paperwidth}
+ \makebox[\linewidth]{\color{QA-sep-line}\rule{4\paperwidth}{#1}}
+ \par
+ }
+
+\NewDocumentEnvironment { QA_void } { } { } { }
+\NewDocumentEnvironment { QA_Q } { D<>{} }
+ {
+ \colorlet{paper}{QA-Q-back}
+ \colorlet{main-text}{QA-Q-text}
+ \colorlet{emph-text}{QA-Q-emph}
+ \begin{tcolorbox}[
+ QA-common,
+ QA-additional,
+ colbacktitle={QA-Q-back},
+ coltitle={QA-Q-text!33!QA-Q-back},
+ colback={QA-Q-back},
+ colupper={QA-Q-text},
+ ]
+ \exp_args:No \str_if_in:nnT { \l__QA_theme_str } { ChatGPT }
+ { \vspace{-.5\parskip} }
+ \vspace{-.5\parskip} % due to "parbox=false"
+ \vspace{-\parskip}
+ \begin{QA-entry}
+ \exp_args:No \str_if_in:nnT { \l__QA_theme_str } { ChatGPT }
+ { \parskip=2\parskip }
+ \item[\hfill\color{QA-Q-text!33!QA-Q-back}\l_QA_logo_code_Q_tl]
+ }
+ {
+ \end{QA-entry}
+ \end{tcolorbox}
+ }
+\NewDocumentEnvironment { QA_A } { D<>{} }
+ {
+ \colorlet{paper}{QA-A-back}
+ \colorlet{main-text}{QA-A-text}
+ \colorlet{emph-text}{QA-A-emph}
+ \begin{tcolorbox}[
+ QA-common,
+ QA-additional,
+ colbacktitle={QA-A-back},
+ coltitle={QA-A-text!33!QA-A-back},
+ colback={QA-A-back},
+ colupper={QA-A-text},
+ ]
+ \exp_args:No \str_if_in:nnT { \l__QA_theme_str } { ChatGPT }
+ { \vspace{-.5\parskip} }
+ \vspace{-.5\parskip} % due to "parbox=false"
+ \vspace{-\parskip}
+ \begin{QA-entry}
+ \exp_args:No \str_if_in:nnT { \l__QA_theme_str } { ChatGPT }
+ { \parskip=2\parskip }
+ \item[\hfill\color{QA-A-text!33!QA-A-back}\l_QA_logo_code_A_tl]
+ }
+ {
+ \end{QA-entry}
+ \end{tcolorbox}
+ }
+\NewDocumentEnvironment { QA_N } { D<>{} }
+ {
+ \colorlet{paper}{QA-N-back}
+ \colorlet{main-text}{QA-N-text}
+ \colorlet{emph-text}{QA-N-emph}
+ \exp_args:No \str_if_in:nnT { \l__QA_theme_str } { ChatGPT }
+ {
+ \colorlet{QA-code-title-back}{QA-A-back}
+ \colorlet{QA-code-title-text}{QA-A-text}
+ }
+ \begin{tcolorbox}[
+ QA-common,
+ % QA-additional,
+ % interior~hidden,
+ colbacktitle={QA-N-back},
+ coltitle={QA-N-text!33!QA-N-back},
+ colback={QA-N-back},
+ colupper={QA-N-text},
+ fontupper=\itshape,
+ left=\l_QA_list_indentation_dim+1em,
+ overlay={\draw[QA-N-text!15!QA-N-back, line~width=.3em] ($(frame.north~west)+(\l_QA_list_indentation_dim+.5em,-2.75mm)$)--($(frame.south~west)+(\l_QA_list_indentation_dim+.5em,2.75mm)$);}
+ ]
+ }
+ {
+ \end{tcolorbox}
+ }
+
+\bool_if:NT \l__QA_answer_outside_the_box_bool
+ {
+ \colorlet{paper}{QA-A-back}
+ \colorlet{main-text}{QA-A-text}
+ \colorlet{emph-text}{QA-A-emph}
+
+ \projlib_paper_set_page_color:n { paper }
+ \projlib_paper_set_text_color:n { main-text }
+
+ \RenewDocumentEnvironment { QA_A } { D<>{} }
+ {
+ \color{QA-A-text}
+ \vspace{1em}
+ \exp_args:No \str_if_in:nnT { \l__QA_theme_str } { ChatGPT }
+ {
+ \vspace{1em}
+ \sffamily
+ \onehalfspacing
+ \vspace{-.5\parskip}
+ }
+ \vspace{-.5\parskip}
+ \begin{QA-entry}[leftmargin=.5mm, itemindent=0pt, labelsep=\l_QA_list_labelsep_dim, labelwidth=3em]
+ \exp_args:No \str_if_in:nnT { \l__QA_theme_str } { ChatGPT }
+ { \parskip=2\parskip }
+ \item[\hfill\color{QA-A-text!33!QA-A-back}\l_QA_logo_code_A_tl]
+ }
+ {
+ \end{QA-entry}
+ \vspace{1em}
+ \exp_args:No \str_if_in:nnT { \l__QA_theme_str } { ChatGPT }
+ { \vspace{1em} }
+ }
+ }
+
+\NewDocumentCommand \SetLogoCode { O{void} m }
+ {
+ \tl_set:cn { l_QA_logo_code_ #1 _tl } { #2 }
+ }
+% Set default logo code
+\SetLogoCode[Q]{\textbf{\l_QA_label_Q_tl}}
+\SetLogoCode[A]{\textbf{\l_QA_label_R_tl}}
+\projlib_langauge_define_multilingual_text:Nn \l_QA_label_Q_tl
+ {
+ , EN = { Q\,: }
+ , FR = { Q: }
+ , DE = { F\,: }
+ , IT = { D\,: }
+ , PT = { P\,: }
+ , BR = { P\,: }
+ , ES = { P\,: }
+ , CN = { Q\,: }
+ , TC = { Q\,: }
+ , JP = { Q\,: }
+ , RU = { B\,: }
+ }
+\projlib_langauge_define_multilingual_text:Nn \l_QA_label_R_tl
+ {
+ , EN = { A\,: }
+ , FR = { R: }
+ , DE = { A\,: }
+ , IT = { R\,: }
+ , PT = { R\,: }
+ , BR = { R\,: }
+ , ES = { R\,: }
+ , CN = { A\,: }
+ , TC = { A\,: }
+ , JP = { A\,: }
+ , RU = { O\,: }
+ }
+
+\prop_new:N \g__QA_prefix_type_prop
+\NewDocumentCommand \QASetTypePrefix { m m }
+ {
+ \clist_map_inline:nn { #2 }
+ {
+ \prop_gput_if_new:Nnn \g__QA_prefix_type_prop { ##1 } { #1 }
+ }
+ }
+\NewDocumentCommand \QAAddTypePrefix { m m }
+ {
+ \prop_gput_if_new:Nnn \g__QA_prefix_type_prop { #2 } { #1 }
+ }
+\NewDocumentCommand \QARemovePrefix { m }
+ {
+ \prop_gremove:Nn \g__QA_prefix_type_prop { #1 }
+ }
+\NewDocumentCommand \QARemoveAllPrefix { }
+ {
+ \prop_gclear:N \g__QA_prefix_type_prop
+ }
+
+% \QASetTypePrefix { void } { VOID }
+% \QASetTypePrefix { Q } { Q: , ? }
+% \QASetTypePrefix { A } { A: , : }
+% \QASetTypePrefix { N } { N: , " }
+\QASetTypePrefix { Q } { Q: , ? , ? }
+\QASetTypePrefix { A } { A: , : , : }
+\QASetTypePrefix { N } { N: , " , “ , ” , 「 }
+
+\AddLanguageSetting [ EN ]
+ {
+ \QARemoveAllPrefix
+ \QASetTypePrefix { Q } { Q: , ? , ? }
+ \QASetTypePrefix { A } { A: , : , : }
+ \QASetTypePrefix { N } { N: , " , “ , ” , 「 }
+ }
+\AddLanguageSetting [ FR ]
+ {
+ \QARemoveAllPrefix
+ \QASetTypePrefix { Q } { Q: , ? , ? }
+ \QASetTypePrefix { A } { R: , : , : }
+ \QASetTypePrefix { N } { N: , " , “ , ” , 「 }
+ }
+\AddLanguageSetting [ DE ]
+ {
+ \QARemoveAllPrefix
+ \QASetTypePrefix { Q } { F: , ? , ? }
+ \QASetTypePrefix { A } { A: , : , : }
+ \QASetTypePrefix { N } { E: , " , “ , ” , 「 }
+ }
+\AddLanguageSetting [ IT ]
+ {
+ \QARemoveAllPrefix
+ \QASetTypePrefix { Q } { D: , ? , ? }
+ \QASetTypePrefix { A } { R: , : , : }
+ \QASetTypePrefix { N } { N: , " , “ , ” , 「 }
+ }
+\AddLanguageSetting [ PT ]
+ {
+ \QARemoveAllPrefix
+ \QASetTypePrefix { Q } { P: , ? , ? }
+ \QASetTypePrefix { A } { R: , : , : }
+ \QASetTypePrefix { N } { N: , " , “ , ” , 「 }
+ }
+\AddLanguageSetting [ BR ]
+ {
+ \QARemoveAllPrefix
+ \QASetTypePrefix { Q } { P: , ? , ? }
+ \QASetTypePrefix { A } { R: , : , : }
+ \QASetTypePrefix { N } { N: , " , “ , ” , 「 }
+ }
+\AddLanguageSetting [ ES ]
+ {
+ \QARemoveAllPrefix
+ \QASetTypePrefix { Q } { P: , ? , ? }
+ \QASetTypePrefix { A } { R: , : , : }
+ \QASetTypePrefix { N } { N: , " , “ , ” , 「 }
+ }
+\AddLanguageSetting [ CN ]
+ {
+ \QARemoveAllPrefix
+ \QASetTypePrefix { Q } { 问: , Q: , ? , ? }
+ \QASetTypePrefix { A } { 答: , A: , : , : }
+ \QASetTypePrefix { N } { 注: , N: , " , “ , ” , 「 }
+ }
+\AddLanguageSetting [ TC ]
+ {
+ \QARemoveAllPrefix
+ \QASetTypePrefix { Q } { 問: , Q: , ? , ? }
+ \QASetTypePrefix { A } { 答: , A: , : , : }
+ \QASetTypePrefix { N } { 註: , N: , " , “ , ” , 「 }
+ }
+\AddLanguageSetting [ JP ]
+ {
+ \QARemoveAllPrefix
+ \QASetTypePrefix { Q } { Q: , ? , ? }
+ \QASetTypePrefix { A } { A: , : , : }
+ \QASetTypePrefix { N } { N: , " , 「 }
+ }
+\AddLanguageSetting [ RU ]
+ {
+ \QARemoveAllPrefix
+ \QASetTypePrefix { Q } { B: , ? }
+ \QASetTypePrefix { A } { O: , : }
+ \QASetTypePrefix { N } { P: , " }
+ }
+
+\tl_new:N \l__QA_current_type_tl
+\tl_set:Nn \l__QA_current_type_tl { void }
+
+% Parse the content
+\bool_new:N \l_QA_regex_no_more_match_bool
+\seq_new:N \l_QA_tmp_seq
+\tl_new:N \l_QA_tmp_tl
+\tl_new:N \g_QA_current_content_tl
+\cs_generate_variant:Nn \regex_split:nnN { nVN }
+\cs_new:Nn \QA_parse_content:N
+ {
+ \tl_set:Nn \l__QA_current_type_tl { void }
+ \regex_split:nVN { \c{par} } #1 \l_QA_tmp_seq
+ \tl_gclear:N #1
+ % \tl_gclear:N \g_QA_current_content_tl
+ \seq_map_inline:Nn \l_QA_tmp_seq
+ {
+ \tl_set:Nn \l_QA_tmp_tl { ❄️ ##1 }
+
+ \regex_replace_all:nnN
+ { \:\:\: }
+ { ⚛ \c{QAInclude} }
+ \l_QA_tmp_tl
+ \regex_replace_all:nnN
+ { \:\: }
+ { ⚛ \c{QAInput} }
+ \l_QA_tmp_tl
+
+ \regex_replace_all:nnN
+ { \=\= }
+ { \c{QAInsertCode} }
+ \l_QA_tmp_tl
+
+ \regex_replace_all:nnN
+ { \#\#\#\#\+ }
+ { ⚛ \c{subsubsection} }
+ \l_QA_tmp_tl
+ \regex_replace_all:nnN
+ { \#\#\#\+ }
+ { ⚛ \c{subsection} }
+ \l_QA_tmp_tl
+ \regex_replace_all:nnN
+ { \#\#\+ }
+ { ⚛ \c{section} }
+ \l_QA_tmp_tl
+ \regex_replace_all:nnN
+ { \#\#\#\# }
+ { ⚛ \c{subsubsection}\* }
+ \l_QA_tmp_tl
+ \regex_replace_all:nnN
+ { \#\#\# }
+ { ⚛ \c{subsection}\* }
+ \l_QA_tmp_tl
+ \regex_replace_all:nnN
+ { \#\# }
+ { ⚛ \c{section}\* }
+ \l_QA_tmp_tl
+
+ \regex_replace_all:nnN
+ { \`\` }
+ { ❝ }
+ \l_QA_tmp_tl
+ \regex_replace_all:nnN
+ { \` (.*?) \` }
+ { \c{QACode} {\1} }
+ \l_QA_tmp_tl
+ \regex_replace_all:nnN
+ { ❝ }
+ { \`\` }
+ \l_QA_tmp_tl
+
+ \regex_replace_once:nnN
+ { >>> \ *? (.*) }
+ { \c{QANote} {\1} }
+ \l_QA_tmp_tl
+ \regex_replace_all:nnN
+ { \ *? >>> \ *? }
+ { }
+ \l_QA_tmp_tl
+
+ \exp_args:Nno \regex_split:nnN { >> } { \l_QA_tmp_tl } \l_tmpa_seq
+ \seq_pop_left:NN \l_tmpa_seq \l_tmpa_tl
+ \tl_set_eq:NN \l_QA_tmp_tl \l_tmpa_tl
+ \seq_map_inline:Nn \l_tmpa_seq
+ {
+ \tl_put_right:Nn \l_QA_tmp_tl
+ { \QACompactCenterText { ####1 } }
+ }
+
+ \regex_replace_all:nnN
+ { \|\| }
+ { \c{QAShowImageCenter} }
+ \l_QA_tmp_tl
+ \regex_replace_all:nnN
+ { \(\( }
+ { \c{QAShowImageLeft} }
+ \l_QA_tmp_tl
+ \regex_replace_all:nnN
+ { \)\) }
+ { \c{QAShowImageRight} }
+ \l_QA_tmp_tl
+
+ \bool_set_false:N \l_QA_regex_no_more_match_bool
+ \bool_do_until:nn \l_QA_regex_no_more_match_bool
+ {
+ \regex_match:nVTF { ❄️ \ *? \+{3} } \l_QA_tmp_tl
+ {
+ \tl_gput_right:Nn \g_QA_current_content_tl { \c_QA_enlarge_page_by_one_line_tl }
+ \regex_replace_once:nnN
+ { ❄️ \ *? \+{3} (.*) }
+ { ❄️ \1 }
+ \l_QA_tmp_tl
+ }
+ {
+ \bool_set_true:N \l_QA_regex_no_more_match_bool
+ }
+ }
+
+ \tl_put_right:Nn \l_QA_tmp_tl { ❄️ }
+ \regex_match:nVT { ❄️ \ *? \-{3,} \ *? ❄️ } \l_QA_tmp_tl
+ {
+ \regex_replace_once:nnN
+ { ❄️ \ *? \-{3,} \ *? }
+ { ❄️ \c{QASepLine} }
+ \l_QA_tmp_tl
+ }
+ \regex_replace_once:nnN { ❄️ (.*) ❄️ } { ❄️ \1 } \l_QA_tmp_tl
+
+ \prop_map_inline:Nn \g__QA_prefix_type_prop
+ {
+ \regex_match:nVTF { ❄️ \ *? ####1 } \l_QA_tmp_tl
+ {% start of a new type
+ % Put the current stored content into output stream
+ \__QA_put_current_content:n { #1 }
+ % Set the new type
+ \tl_set:Nn \l__QA_current_type_tl { ####2 }
+ \regex_replace_once:nnN
+ { ❄️ \ *? ####1 (.*) }
+ { ❄️ \1 }
+ \l_QA_tmp_tl
+ }
+ {% normal paragraph
+ \regex_match:nVTF { ❄️ \ *? ⚛ } \l_QA_tmp_tl
+ {% Things that should be put into separate group
+ % Put the current stored content into output stream
+ \__QA_put_current_content:n { #1 }
+ % Directly put the current line into the output stream
+ \regex_replace_all:nnN { ⚛ } { } \l_QA_tmp_tl
+ \regex_replace_once:nnN { ❄️ } { } \l_QA_tmp_tl
+ \tl_gput_right:No #1 { \l_QA_tmp_tl \par }
+ \tl_clear:N \l_QA_tmp_tl
+ % Reset the current type (!!this certainly breaks the usual behavior of \input and \include!!)
+ \tl_set:Nn \l__QA_current_type_tl { void }
+ }
+ {
+ % Do nothing
+ }
+ }
+ }
+
+ % \regex_replace_once:nnN
+ % { ❄️ \ *? \[\*(.*?)\] (.*) }
+ % { \c{QAItem} {\1} {\2} }
+ % \l_QA_tmp_tl
+ %% Process the first and wrap the others inside
+ \regex_replace_once:nnN
+ { ❄️ \ *? \[\*(.*?)\] (.*) }
+ { \c{QAItem} {\1} {\2} }
+ \l_QA_tmp_tl
+ %% Process the middle ones
+ \bool_set_false:N \l_QA_regex_no_more_match_bool
+ \bool_do_until:nn \l_QA_regex_no_more_match_bool
+ {
+ \regex_match:nVTF { \[\*(.*?)\] (.*?) \[\* } \l_QA_tmp_tl
+ {
+ \regex_replace_once:nnN
+ { \[\*(.*?)\] (.*?) \[\* }
+ { \c{QAItem} {\1} {\2} \c{QAadjustitem} \[\* }
+ \l_QA_tmp_tl
+ }
+ {
+ \bool_set_true:N \l_QA_regex_no_more_match_bool
+ }
+ }
+ %% Process the last one
+ \regex_replace_once:nnN
+ { \[\*(.*?)\] (.*) }
+ { \c{QAItem} {\1} {\2} }
+ \l_QA_tmp_tl
+
+ %% Process the first and wrap the others inside
+ \regex_replace_once:nnN
+ { ❄️ \ *? 【\*(.*?)】 (.*) }
+ { \c{QAItem} {\1} {\2} }
+ \l_QA_tmp_tl
+ %% Process the middle ones
+ \bool_set_false:N \l_QA_regex_no_more_match_bool
+ \bool_do_until:nn \l_QA_regex_no_more_match_bool
+ {
+ \regex_match:nVTF { 【\*(.*?)】 (.*?) 【\* } \l_QA_tmp_tl
+ {
+ \regex_replace_once:nnN
+ { 【\*(.*?)】 (.*?) 【\* }
+ { \c{QAItem} {\1} {\2} \c{QAadjustitem} 【\* }
+ \l_QA_tmp_tl
+ }
+ {
+ \bool_set_true:N \l_QA_regex_no_more_match_bool
+ }
+ }
+ %% Process the last one
+ \regex_replace_once:nnN
+ { 【\*(.*?)】 (.*) }
+ { \c{QAItem} {\1} {\2} }
+ \l_QA_tmp_tl
+
+ \regex_replace_once:nnN
+ { ❄️ \ *? \[(.*?)\] (\*?) (.*) }
+ { \c{QAEnum} \2 {\1} {\3} }
+ \l_QA_tmp_tl
+ \regex_replace_once:nnN
+ { ❄️ \ *? 【(.*?)】 (\*?) (.*) }
+ { \c{QAEnum} \2 {\1} {\3} }
+ \l_QA_tmp_tl
+
+ \regex_replace_all:nnN
+ { \*\*\* (.*?) \*\*\* }
+ { \c{textbf} { \c{emph} {\1} } }
+ \l_QA_tmp_tl
+ \regex_replace_all:nnN
+ { \*\* (.*?) \*\* }
+ { \c{textbf} {\1} }
+ \l_QA_tmp_tl
+ \regex_replace_all:nnN
+ { \* (.*?) \* }
+ { \c{emph} {\1} }
+ \l_QA_tmp_tl
+
+ \regex_replace_once:nnN { ❄️ } { } \l_QA_tmp_tl
+
+ \tl_gput_right:NV \g_QA_current_content_tl \l_QA_tmp_tl
+ \tl_if_empty:NF \g_QA_current_content_tl
+ {
+ \tl_gput_right:Nn \g_QA_current_content_tl { \par }
+ }
+ }
+ \__QA_put_current_content:n { #1 }
+ }
+
+\box_new:N \l__QA_tmp_box
+\cs_new:Nn \__QA_put_current_content:n
+ {
+ \tl_if_empty:NF \g_QA_current_content_tl
+ {
+ \tl_gput_right:Ne #1 { \exp_not:N \begin { QA_\l__QA_current_type_tl } }
+ \tl_gput_right:No #1 { \g_QA_current_content_tl }
+ \tl_gput_right:Ne #1 { \exp_not:N \end { QA_\l__QA_current_type_tl } }
+ }
+ \tl_gclear:N \g_QA_current_content_tl
+ }
+
+\bool_if:NTF \l__QA_scroll_bool
+ {
+ \tl_const:Nn \c_QA_enlarge_page_by_one_line_tl {}
+ \geometry{
+ papersize={7in,\maxdimen},
+ % top=.75in,bottom=.75in,
+ top=0in,bottom=0in,
+ % left=.75in,right=.66in,
+ left=\l_QA_list_indentation_dim+1em,right=4em,
+ marginparsep=.75em,
+ marginparwidth=.75in,
+ footnotesep=2em plus 2pt minus 2pt,
+ }
+ \hook_gput_code:nnn { begindocument } { Q-and-A }
+ {
+ \setbox0=\vbox
+ \bgroup
+ \begin { Q-and-A }
+ }
+ \providecommand{\pdfpageheight}{\pageheight}
+ \hook_gput_code:nnn { enddocument } { Q-and-A }
+ {
+ \end { Q-and-A }
+ \vspace{-1mm}
+ \egroup
+ \dimen0=\dp0
+ \pdfpageheight=\dimexpr\ht0\relax
+ % \ifdim\pdfpageheight<10in
+ % \pdfpageheight=10in
+ % \fi
+ \unvbox0\kern-\dimen0
+ }
+ }
+ {
+ \tl_const:Nn \c_QA_enlarge_page_by_one_line_tl { \enlargethispage{\baselineskip} }
+ \geometry{
+ papersize={7in,10in},
+ % top=.75in,bottom=.75in,
+ top=0in,bottom=0in,
+ % left=.75in,right=.66in,
+ left=\l_QA_list_indentation_dim+1em,right=4em,
+ marginparsep=.75em,
+ marginparwidth=.75in,
+ footnotesep=2em plus 2pt minus 2pt,
+ }
+ \hook_gput_code:nnn { begindocument/end } { Q-and-A }
+ {
+ \begin { Q-and-A }
+ }
+ \hook_gput_code:nnn { enddocument } { Q-and-A }
+ {
+ \end { Q-and-A }
+ }
+ }
+
+\pagestyle { empty }
+
+\def\textasterisk{*}
+\def\textbacktick{`}
+\def\textcolon{:}
+\def\textequalsign{=}
+\def\textleftparen{(}
+\def\textrightparen{)}
+\def\textsharp{\#}
+\def\textvert{|}
+
+\endinput
+%%
+%% End of file `Q-and-A.cls'.
diff --git a/macros/latex/contrib/q-and-a/README.md b/macros/latex/contrib/q-and-a/README.md
new file mode 100644
index 0000000000..4c3d474cc1
--- /dev/null
+++ b/macros/latex/contrib/q-and-a/README.md
@@ -0,0 +1,61 @@
+<!-- Copyright (C) 2023 by Jinwen XU -->
+
+# `Q-and-A` — Typesetting Q\&A-style conversation made easier
+
+## Introduction
+
+`Q-and-A` is a LaTeX document class for you to typeset Q&A-style conversation. It turns simple pure text Q&A dialog into carefully designed document.
+
+Notably, it features two themes, `ChatGPT-light` and `ChatGPT-dark`, enabling you to format your Q&A dialog in a way that closely resembles the interface of ChatGPT.
+
+## Installation and preparation
+
+### How to install this package
+
+If you are using TeX Live 2024 or newer, or the most recent version of MikTeX, then this package should already be included, and you don't need to do anything.
+
+Otherwise, you need to check for package update to see if you can receive it. In case not, you can always go to [the CTAN page](https://ctan.org/pkg/Q-and-A) to download the `.zip` file with all related files included.
+
+## Usage
+
+Please refer to [the documentation](https://github.com/Jinwen-XU/Q-and-A/blob/main/doc/Q-and-A-doc.pdf) for detailed usage.
+
+> You may get started by exploring [the demo documents](https://github.com/Jinwen-XU/Q-and-A/tree/main/demo).
+
+> If you don't find what you were expecting, or if you would like some elements to be changed or improved, feel free to post a feature request via [the GitHub issue](https://github.com/Jinwen-XU/Q-and-A/issues).
+
+
+## TeXnical details
+
+### Engines and base classes
+- With pdfLaTeX, the base class is `minimart`.
+- With XeLaTeX or LuaLaTeX, the base class is `einfart`.
+
+### Regarding the fonts
+
+If you are using XeLaTeX or LuaLaTeX to compile your document, then the current document class requires the following open-source fonts that are not included in the standard TeX collection:
+
+- The Source Han font series at [Adobe Fonts](https://github.com/adobe-fonts). More specifically:
+ - Source Han Serif, [go to its Release page](https://github.com/adobe-fonts/source-han-serif/releases).
+ - Source Han Sans, [go to its Release page](https://github.com/adobe-fonts/source-han-sans/releases).
+ - Source Han Mono, [go to its Release page](https://github.com/adobe-fonts/source-han-mono/releases).
+ > It is recommended to download the Super-OTC version, so that the total download size would be smaller, and the installation would be easier.
+
+These are necessary if you wish to write your document in Chinese (either simplified or traditional) or Japanese. Also, without these fonts installed, the compilation speed might be much slower — the compilation would still pass, but the system shall spend (quite) some time verifying that the fonts are indeed missing before switching to the fallback fonts.
+
+### Functionality
+The main features are achieved with the power of LaTeX3's regex functionality. It scans the content paragraph by paragraph and converts recognized patterns into corresponding TeX commands.
+However, this comes with a price: in order to scan the content, it is firstly stored in a macro, and that means that you cannot use commands like `\verb` in your main text.
+Also, synctex won't work properly.
+
+### Language and date format
+Language and date format can both be set in two ways: as class option or with corresponding commands.
+- The user-level command for setting language is `\UseLanguage`, provided by `projlib-language`; the one for setting date format is `\SetDatetimeInputFormat`, provided by `projlib-date`.
+- When you set the language, it is not exactly the same using class option or using command: when you select a language via class option, only the setting for this language would be loaded; however, with `\UseLanguage`, it would load *all* the language settings and then switch to your selected one. Sometimes the page breaking behavior differs slightly. Personally I prefer the `\UseLanguage` approach, for this would allow you to switch language in the middle of your document.
+
+### Scroll mode
+The scroll mode is achieved by directly accessing `\pdfpageheight` (pdfTeX and XeTeX) or `\pageheight` (LuaTeX). <!-- The minimal page height is set to be `10in`. --> It is worth noting that in order to calculate the height needed, the entire content are put into a single box, which puts a limitation on the length of your document (but this usually wouldn't be a problem).
+
+# License
+
+This work is released under the LaTeX Project Public License, v1.3c or later.
diff --git a/macros/latex/contrib/q-and-a/demo/lang-fr/Q-and-A-demo-fr-content.tex b/macros/latex/contrib/q-and-a/demo/lang-fr/Q-and-A-demo-fr-content.tex
new file mode 100644
index 0000000000..ea8ff4d88e
--- /dev/null
+++ b/macros/latex/contrib/q-and-a/demo/lang-fr/Q-and-A-demo-fr-content.tex
@@ -0,0 +1,92 @@
+% La conversation suivante est générée par ChatGPT (avec GPT-3.5).
+
+Q:
+ Qu'est-ce que la programmation informatique ?
+
+R:
+ La programmation informatique est le processus de création d'instructions pour un ordinateur afin qu'il exécute des tâches spécifiques. Elle est l'une des compétences fondamentales dans le domaine de l'informatique. La programmation consiste à écrire des lignes de code dans un langage compréhensible par la machine. Ces instructions sont ensuite exécutées séquentiellement, ce qui permet de réaliser diverses opérations, du simple calcul mathématique à la gestion de bases de données complexes ou à la création de logiciels.
+
+Q:
+ Quels sont les principaux langages de programmation ?
+
+R:
+ Il existe une multitude de langages de programmation, chacun ayant ses caractéristiques et ses domaines d'application particuliers. Parmi les langages de programmation les plus courants, on trouve :
+
+ [Python]
+ Très apprécié pour sa simplicité et sa polyvalence, il est largement utilisé en science des données, développement web et automatisation.
+
+ [Java]
+ Connu pour sa portabilité, il est utilisé dans le développement d'applications Android, de logiciels d'entreprise et de systèmes embarqués.
+
+ [C++]
+ Il offre des performances élevées et est couramment utilisé pour les jeux, les applications de bureau et les systèmes temps réel.
+
+ [JavaScript]
+ Le langage de prédilection pour le développement web, il est exécuté dans les navigateurs et permet de créer des applications interactives.
+
+ [Ruby]
+ Apprécié pour sa simplicité syntaxique et son élégance, il est couramment utilisé dans le développement web et les scripts.
+
+Q:
+ Comment écrire une boucle `for` en Python ?
+
+R:
+ En Python, les boucles `for` sont couramment utilisées pour parcourir des séquences de données, telles que des listes, des chaînes de caractères, ou des dictionnaires. Voici un exemple de boucle `for` en Python :
+
+ == [python] {code/Q-and-A-demo-fr-code-for.py}
+
+ Dans cet exemple, la boucle `for` parcourt les valeurs de 0 à 4, et à chaque itération, la valeur de `i` est imprimée. Cela permet d'effectuer des opérations répétitives de manière efficace.
+
+Q:
+ Qu'est-ce qu'une liste en Python ?
+
+R:
+ En Python, une liste est une structure de données qui permet de stocker une collection ordonnée d'éléments. Les éléments d'une liste peuvent être de différents types, tels que des nombres, des chaînes de caractères, ou même d'autres listes. Les listes sont très flexibles et polyvalentes, ce qui en fait un choix courant pour le stockage de données. Voici un exemple de liste en Python :
+
+ == [python] {code/Q-and-A-demo-fr-code-list.py}
+
+ On peut accéder aux éléments de la liste en utilisant leur indice, par exemple, `ma\_liste[2]` renverra la valeur 3, car les indices commencent à 0.
+
+Q:
+ Quelle est la différence entre une variable locale et une variable globale en programmation?
+
+R:
+ En programmation, la portée des variables est un concept important. Une variable locale est déclarée à l'intérieur d'une fonction et n'est accessible qu'à l'intérieur de cette fonction. Elle n'existe que pendant l'exécution de la fonction, et son nom est isolé du reste du programme. En revanche, une variable globale est déclarée en dehors de toutes les fonctions et peut être utilisée partout dans le programme. Elle conserve sa valeur entre les appels de fonctions et peut être modifiée par n'importe quelle partie du code. Il est essentiel de comprendre la portée des variables pour éviter des erreurs inattendues dans votre code.
+
+Q:
+ Comment déclarer une fonction en Python?
+
+R:
+ Pour déclarer une fonction en Python, utilisez le mot-clé `def` suivi du nom de la fonction et de ses paramètres. Voici un exemple de déclaration de fonction :
+
+ == [python] {code/Q-and-A-demo-fr-code-func.py}
+
+ Dans cet exemple, `ma\_fonction` est le nom de la fonction, et elle prend un paramètre `parametre`. À l'intérieur de la fonction, des opérations sont effectuées, et la valeur résultante est renvoyée à l'appelant à l'aide du mot-clé `return`. Les fonctions sont essentielles pour organiser le code et le rendre réutilisable.
+
+Q:
+ Quelles sont les étapes pour résoudre un problème de programmation?
+
+R:
+ La résolution de problèmes de programmation implique plusieurs étapes essentielles.
+
+ [Comprendre le problème]
+ [*] Identifier les objectifs.
+ [*] Analyser les données d'entrée.
+
+ [Concevoir une solution]
+ [*] Élaborer un algorithme.
+ [*] Utiliser des listes pour représenter des structures de données complexes.
+
+ [Écrire le code]
+ [*] Transformer votre algorithme en code.
+ [*] Utiliser des listes et des boucles pour traiter les données.
+
+ [Tester et déboguer le code]
+ [*] Vérifier si le code fonctionne correctement.
+ [*] Corriger les erreurs (bugs) éventuels.
+
+ [Optimiser si nécessaire]
+ [*] Améliorer l'efficacité du code.
+ [*] Utiliser des techniques avancées avec des listes pour optimiser les performances.
+
+ Cette approche structurée aide les programmeurs à résoudre efficacement les problèmes informatiques.
diff --git a/macros/latex/contrib/q-and-a/demo/lang-fr/Q-and-A-demo-fr.pdf b/macros/latex/contrib/q-and-a/demo/lang-fr/Q-and-A-demo-fr.pdf
new file mode 100644
index 0000000000..a1307f1deb
--- /dev/null
+++ b/macros/latex/contrib/q-and-a/demo/lang-fr/Q-and-A-demo-fr.pdf
Binary files differ
diff --git a/macros/latex/contrib/q-and-a/demo/lang-fr/Q-and-A-demo-fr.tex b/macros/latex/contrib/q-and-a/demo/lang-fr/Q-and-A-demo-fr.tex
new file mode 100644
index 0000000000..4f5ae4eded
--- /dev/null
+++ b/macros/latex/contrib/q-and-a/demo/lang-fr/Q-and-A-demo-fr.tex
@@ -0,0 +1,26 @@
+\documentclass[%11pt,
+ scroll,
+]{Q-and-A}
+
+\UseLanguage{French}
+
+\begin{document}
+
+
+:: {Q-and-A-demo-fr-content}
+
+
+---
+
+"
+ Voici le code de cette conversation.
+
+ == {Q-and-A-demo-fr-content}
+
+"
+ Voici le code du document principal.
+
+ == [latex] {\jobname}
+
+
+\end{document}
diff --git a/macros/latex/contrib/q-and-a/demo/lang-fr/code/Q-and-A-demo-fr-code-for.py b/macros/latex/contrib/q-and-a/demo/lang-fr/code/Q-and-A-demo-fr-code-for.py
new file mode 100644
index 0000000000..7049de3509
--- /dev/null
+++ b/macros/latex/contrib/q-and-a/demo/lang-fr/code/Q-and-A-demo-fr-code-for.py
@@ -0,0 +1,2 @@
+for i in range(5):
+ print(i) \ No newline at end of file
diff --git a/macros/latex/contrib/q-and-a/demo/lang-fr/code/Q-and-A-demo-fr-code-func.py b/macros/latex/contrib/q-and-a/demo/lang-fr/code/Q-and-A-demo-fr-code-func.py
new file mode 100644
index 0000000000..0e1674e63e
--- /dev/null
+++ b/macros/latex/contrib/q-and-a/demo/lang-fr/code/Q-and-A-demo-fr-code-func.py
@@ -0,0 +1,4 @@
+def ma_fonction(parametre):
+ # Corps de la fonction
+ resultat = parametre * 2
+ return resultat \ No newline at end of file
diff --git a/macros/latex/contrib/q-and-a/demo/lang-fr/code/Q-and-A-demo-fr-code-list.py b/macros/latex/contrib/q-and-a/demo/lang-fr/code/Q-and-A-demo-fr-code-list.py
new file mode 100644
index 0000000000..0775113925
--- /dev/null
+++ b/macros/latex/contrib/q-and-a/demo/lang-fr/code/Q-and-A-demo-fr-code-list.py
@@ -0,0 +1 @@
+ma_liste = [1, 2, 3, 4, 5] \ No newline at end of file
diff --git a/macros/latex/contrib/q-and-a/demo/theme-ChatGPT/Q-and-A-demo-ChatGPT-content.tex b/macros/latex/contrib/q-and-a/demo/theme-ChatGPT/Q-and-A-demo-ChatGPT-content.tex
new file mode 100644
index 0000000000..8db7a03a33
--- /dev/null
+++ b/macros/latex/contrib/q-and-a/demo/theme-ChatGPT/Q-and-A-demo-ChatGPT-content.tex
@@ -0,0 +1,81 @@
+"
+ The following conversation is generated by ChatGPT (with GPT-3.5) on \TheDate{2023-11-01}.
+
+?
+ What is artificial intelligence (AI)?
+
+:
+ Artificial intelligence, or AI, refers to the development of computer systems that can perform tasks that typically require human intelligence, such as learning, reasoning, problem-solving, and decision-making. AI technologies aim to simulate human cognitive functions in machines, enabling them to understand and respond to data, make predictions, and adapt to changing circumstances.
+
+?
+ What are some common applications of AI?
+
+:
+ AI has a wide range of applications, including:
+
+ [Natural Language Processing (NLP)]
+ [*] Chatbots
+ [*] Language translation
+ [*] Sentiment analysis
+
+ [Computer Vision]
+ [*] Image and video analysis
+ [*] Facial recognition
+ [*] Autonomous vehicles
+
+ [Machine Learning]
+ [*] Predictive analytics
+ [*] Recommendation systems
+ [*] Fraud detection
+
+ [Robotics]
+ [*] Automation in manufacturing
+ [*] Healthcare assistance
+ [*] Service industries
+
+ [Healthcare]
+ [*] Disease diagnosis
+ [*] Drug discovery
+ [*] Personalized treatment plans
+
+ [Finance]
+ [*] Algorithmic trading
+ [*] Risk assessment
+ [*] Customer support
+
+?
+ How does machine learning relate to AI?
+
+:
+ Machine learning is a subfield of AI that focuses on developing algorithms and models that allow computers to learn from and make predictions or decisions based on data. It's a crucial component of AI because it enables systems to improve their performance over time by learning from past experiences.
+
+?
+ Are there different types of machine learning?
+
+:
+ Yes, there are three main types of machine learning:
+
+ [Supervised Learning]
+ In this type, the model is trained on labeled data, making predictions based on known examples.
+
+ [Unsupervised Learning]
+ Unsupervised learning involves finding patterns or structures in unlabeled data without specific guidance.
+
+ [Reinforcement Learning]
+ Reinforcement learning is about training agents to make sequences of decisions to maximize a reward in an environment.
+
+?
+ Can you provide an example of Python code for a simple machine learning model?
+
+:
+ Certainly! Here's a basic Python code example for training a linear regression model using the popular scikit-learn library:
+
+ == [python] {code/Q-and-A-example-code-1.py}
+
+ This code demonstrates a simple linear regression model for predicting housing prices. You can use scikit-learn to create and evaluate various machine learning models in Python.
+
+?
+ What are some ethical considerations in AI and machine learning?
+
+:
+ Ethical concerns in AI and machine learning include issues like bias in algorithms, data privacy, job displacement due to automation, and the responsible use of AI in areas like healthcare and law enforcement. It's important to address these concerns to ensure that AI benefits society as a whole.
diff --git a/macros/latex/contrib/q-and-a/demo/theme-ChatGPT/Q-and-A-demo-ChatGPT-dark.pdf b/macros/latex/contrib/q-and-a/demo/theme-ChatGPT/Q-and-A-demo-ChatGPT-dark.pdf
new file mode 100644
index 0000000000..99b80904b1
--- /dev/null
+++ b/macros/latex/contrib/q-and-a/demo/theme-ChatGPT/Q-and-A-demo-ChatGPT-dark.pdf
Binary files differ
diff --git a/macros/latex/contrib/q-and-a/demo/theme-ChatGPT/Q-and-A-demo-ChatGPT-light.pdf b/macros/latex/contrib/q-and-a/demo/theme-ChatGPT/Q-and-A-demo-ChatGPT-light.pdf
new file mode 100644
index 0000000000..69175ceb7f
--- /dev/null
+++ b/macros/latex/contrib/q-and-a/demo/theme-ChatGPT/Q-and-A-demo-ChatGPT-light.pdf
Binary files differ
diff --git a/macros/latex/contrib/q-and-a/demo/theme-ChatGPT/Q-and-A-demo-ChatGPT.tex b/macros/latex/contrib/q-and-a/demo/theme-ChatGPT/Q-and-A-demo-ChatGPT.tex
new file mode 100644
index 0000000000..318bc65ee7
--- /dev/null
+++ b/macros/latex/contrib/q-and-a/demo/theme-ChatGPT/Q-and-A-demo-ChatGPT.tex
@@ -0,0 +1,28 @@
+\documentclass[%11pt,
+ use theme = ChatGPT-light,
+ % use theme = ChatGPT-dark,
+ scroll,
+]{Q-and-A}
+
+
+\SetLogoCode[Q]{\smash{\raisebox{-.45\baselineskip}{\includegraphics[height=1.35\baselineskip]{Q-and-A-demo-logo-User}}}}
+\SetLogoCode[A]{\smash{\raisebox{-.45\baselineskip}{\includegraphics[height=1.35\baselineskip]{Q-and-A-demo-logo-ChatGPT}}}}
+
+
+\begin{document}
+
+
+:: {Q-and-A-demo-ChatGPT-content}
+
+"
+ Below is the code of this conversation.
+
+ == {Q-and-A-demo-ChatGPT-content}
+
+"
+ Below is the code of the main document.
+
+ == [latex] {\jobname}
+
+
+\end{document}
diff --git a/macros/latex/contrib/q-and-a/demo/theme-ChatGPT/code/Q-and-A-example-code-1.py b/macros/latex/contrib/q-and-a/demo/theme-ChatGPT/code/Q-and-A-example-code-1.py
new file mode 100644
index 0000000000..ac8e3e09c0
--- /dev/null
+++ b/macros/latex/contrib/q-and-a/demo/theme-ChatGPT/code/Q-and-A-example-code-1.py
@@ -0,0 +1,25 @@
+# Import the necessary libraries
+from sklearn import datasets
+from sklearn.model_selection import train_test_split
+from sklearn.linear_model import LinearRegression
+from sklearn.metrics import mean_squared_error
+
+# Load a sample dataset (e.g., the Boston Housing dataset)
+data = datasets.load_boston()
+X, y = data.data, data.target
+
+# Split the dataset into training and testing sets
+X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
+
+# Create a linear regression model
+model = LinearRegression()
+
+# Train the model on the training data
+model.fit(X_train, y_train)
+
+# Make predictions on the test data
+y_pred = model.predict(X_test)
+
+# Calculate the mean squared error to evaluate the model
+mse = mean_squared_error(y_test, y_pred)
+print(f"Mean Squared Error: {mse}") \ No newline at end of file
diff --git a/macros/latex/contrib/q-and-a/demo/theme-ChatGPT/images/Q-and-A-demo-logo-ChatGPT.pdf b/macros/latex/contrib/q-and-a/demo/theme-ChatGPT/images/Q-and-A-demo-logo-ChatGPT.pdf
new file mode 100644
index 0000000000..6ab76f7083
--- /dev/null
+++ b/macros/latex/contrib/q-and-a/demo/theme-ChatGPT/images/Q-and-A-demo-logo-ChatGPT.pdf
Binary files differ
diff --git a/macros/latex/contrib/q-and-a/demo/theme-ChatGPT/images/Q-and-A-demo-logo-User.pdf b/macros/latex/contrib/q-and-a/demo/theme-ChatGPT/images/Q-and-A-demo-logo-User.pdf
new file mode 100644
index 0000000000..fc3a741085
--- /dev/null
+++ b/macros/latex/contrib/q-and-a/demo/theme-ChatGPT/images/Q-and-A-demo-logo-User.pdf
Binary files differ
diff --git a/macros/latex/contrib/q-and-a/doc/Q-and-A-doc.pdf b/macros/latex/contrib/q-and-a/doc/Q-and-A-doc.pdf
new file mode 100644
index 0000000000..6c884038c4
--- /dev/null
+++ b/macros/latex/contrib/q-and-a/doc/Q-and-A-doc.pdf
Binary files differ
diff --git a/macros/latex/contrib/q-and-a/doc/Q-and-A-doc.tex b/macros/latex/contrib/q-and-a/doc/Q-and-A-doc.tex
new file mode 100644
index 0000000000..5405916bad
--- /dev/null
+++ b/macros/latex/contrib/q-and-a/doc/Q-and-A-doc.tex
@@ -0,0 +1,269 @@
+\documentclass[%11pt,
+ use style = classical,
+ scroll,
+]{Q-and-A}
+
+\def\PackageVersion{2023/11/05}
+\def\PackageSubVersion{}
+
+\newcommand{\QApackage}{{\normalfont\textsf{Q-and-A}}}
+
+
+\title{\QApackage{}\\\smallskip\itshape Typesetting Q\&A-style conversation made easier}
+\author{Jinwen XU}
+% \thanks{Corresponding to: \texttt{\QApackage{}~\PackageVersion\PackageSubVersion}}
+\date{\TheDate{\PackageVersion}[only-year-month], in Paris}
+
+
+\newcommand{\meta}[1]{$\langle${\normalfont\itshape#1}$\rangle$}
+
+
+\begin{document}
+
+\maketitle
+
+"
+ Corresponding to: {\normalfont\texttt{\QApackage{}~\PackageVersion\PackageSubVersion}}.
+
+
+##+ {Introduction}
+
+?
+ What is this?
+
+:
+ \QApackage{} is a \LaTeX{} document class for you to typeset Q\&A-style conversation. It turns a simple pure text Q\&A dialog like this:
+
+ == {code/Q-and-A-doc-code-sample-content.tex}
+
+ into a carefully designed document like this:
+
+ \begin{center}
+ \fbox{\includegraphics[width=.67\textwidth]{code/Q-and-A-doc-code-sample-content-result.pdf}}
+ \end{center}
+
+
+##+ {Preparation}
+
+?
+ That is nice. How can I use it? Is there anything that needs to be prepared?
+
+:
+ You should make sure that this document class is properly installed.
+
+ If you are using TeX Live 2024 or newer, or the most recent version of MikTeX, then this package should already be included, and you don't need to do anything.
+
+ Otherwise, you need to check for package update to see if you can receive it. In case not, you can always go to \href{https://ctan.org/pkg/Q-and-A}{the CTAN page} to download the `.zip` file with all related files included.
+
+
+##+ {Usage}
+
+?
+ Now that I have successfully installed it, could you propose an example of usage?
+
+:
+ Of course. A typical document looks like this:
+
+ == [latex] {code/Q-and-A-doc-code-sample-document.tex}
+
+ The available class options include:
+ \begin{itemize}
+ \item Font size options such as `11pt`, `12pt`.
+ \item `scroll`: turns the scroll mode on, which generates a single-page pdf similar to a long screenshot. It is recommended to use this option if your document contains some large piece of code.
+ \item `use theme = \meta{theme}`: use the selected theme, available choices include: `default` (like the current document), `ChatGPT-light` and `ChatGPT-dark` (see the demo documents).
+ \item `answer outside the box`, or `answer out of the box` (or even omit `the`): enables another implementation for printing the answer that does not involve putting it into a colored box. This would be useful if the answers contain many long pieces of code while you still want the pages to break normally.
+ \end{itemize}
+
+?
+ What about the main content?
+
+:
+ You have already seen an example of the main content. As you might have noticed, there are several syntaxes. Let me explain.
+
+ [Questions (Q), Answers (A), and Narrations (N)]
+ \begin{itemize}
+ \item A question begins with the prefix `Q:` or `?`.
+ \item An answer begins with the prefix `A:` or `:`.
+ \item A narration begins with the prefix `N:` or `"`.
+ \end{itemize}
+ >>> Note that this depends on the current language. The prefixes `?`, `:` and `"` being universal, yet~—
+ \begin{itemize}
+ \item for French, it is Q\&R\&N, thus the alphabetical prefixes become `Q:`, `R:` and `N:`;
+ \item for German, it is F\&A\&E, thus the alphabetical prefixes become `F:`, `A:` and `E:`;
+ \item for Italian, it is D\&R\&N, thus the alphabetical prefixes become `D:`, `R:` and `N:`;
+ \item for Portuguese and Brazilian, it is P\&R\&N, thus the alphabetical prefixes become `P:`, `R:` and `N:`;
+ \item for Russian, it is B\&O\&P, thus the alphabetical prefixes become `B:`, `O:` and `P:`;
+ \item for Spanish, it is P\&R\&N, thus the alphabetical prefixes become `P:`, `R:` and `N:`;
+ \item for simplified Chinese, it is also possible to use the prefix `问:` for questions, `答:` for answers, and `注:` for narrations; similarly for traditional Chinese;
+ \item for Chinese or Japanese, it is also possible to use the prefix `?` for questions, `:` for answers, and `“`, `”` or `「` for narrations.
+ \end{itemize}
+
+ [Emphasize and Bold]
+ \begin{itemize}
+ \item Use `\textasterisk\meta{text}\textasterisk` to emphasis `\meta{text}`.
+ \item Use `\textasterisk\textasterisk\meta{text}\textasterisk\textasterisk` to make `\meta{text}` into boldface.
+ \item Use `\textasterisk\textasterisk\textasterisk\meta{text}\textasterisk\textasterisk\textasterisk` to combine the previous effects.
+ \end{itemize}
+
+ [Enumerate and Itemize]
+ \begin{itemize}
+ \item **Emphasized version:**
+ \begin{itemize}
+ \item An emphasized `enumerate` is marked by `[\meta{text}]` *at the beginning*, where `\meta{text}` is the text to be emphasized. The numbering is reset at the end of each answer.
+ \QANote{If you wish to restart the numbering from \( 1 \), write an asterisk after the final bracket: `[\meta{text}]\textasterisk`.}
+ \item An emphasized `itemize` is marked by `[\textasterisk\meta{text}]`, where `\meta{text}` is the text to be emphasized.
+ \end{itemize}
+ \item **Normal version:**
+ \begin{itemize}
+ \item When `\meta{text}` is empty, you get the usual appearance of `enumerate` or `itemize`.
+ \end{itemize}
+ \end{itemize}
+ \QANote{With this method of writing, each emphasized `enumerate` and `itemize` must be put into a separate paragraph, and the lists cannot be nested. The usual `enumerate` and `itemize` environments would still be useful if you need nested lists.}
+
+ [Images]
+ Displayed images can be included via one of the following ways:
+ \begin{itemize}
+ \item `\textvert\textvert{} <\meta{width}> \{\meta{image file name}\}` or `\textvert\textvert{} \{\meta{image file name}\} <\meta{width}>`: display in the center.
+ \item `\textleftparen\textleftparen{} <\meta{width}> \{\meta{image file name}\}` or `\textleftparen\textleftparen{} \{\meta{image file name}\} <\meta{width}>`: display on the left.
+ \item `\textrightparen\textrightparen{} <\meta{width}> \{\meta{image file name}\}` or `\textrightparen\textrightparen{} \{\meta{image file name}\} <\meta{width}>`: display on the right.
+ \end{itemize}
+ \QANote{The `\meta{width}` is optional. Here, `\meta{width}` is a number like `0.75`, the unit is `\textbackslash linewidth`. When `\meta{width}` is not given, the width would be full `\textbackslash linewidth`.}
+ \begin{itemize}
+ \item For centered image, the caption can be written via `\textgreater\textgreater{} \meta{caption text}`.
+ \end{itemize}
+ \QANote{Currently, the `\meta{caption text}` shall be directly printed in the center. You may wish to add a pair of parentheses around it.}
+
+ [Code]
+ Due to the current implementation of this document class, it is unfortunate that you cannot directly insert source code in your document. There are some workarounds, though.
+ \begin{itemize}
+ \item For *inline* code, you may simply write it between two backticks `\textbacktick\meta{code}\textbacktick`, similar to the Markdown syntax. However, be aware that special characters need to be escaped, for example, `\textbackslash` should be written as `\textbackslash textbackslash`, `\{` should be written as `\textbackslash\{`, `\%` should be written as `\textbackslash\%`, etc.
+ \item For *displayed* code, stored the code into a separate file, and then use `\textequalsign\textequalsign{} \{\meta{file name}\}` to print~it. You may also use an optional argument like `\textequalsign\textequalsign{} [\meta{language}] \{\meta{file name}\}` to select the language of your code.
+ \QANote{If the answers contain many long pieces of code, you may consider using the class option `answer outside the box`.}
+ \end{itemize}
+
+ [Sections]
+ \begin{itemize}
+ \item You may start a new (*unnumbered*) ---
+ \begin{itemize}
+ \item section, via `\textsharp\textsharp{} \{\meta{section title}\}`;
+ \item subsection, via `\textsharp\textsharp\textsharp{} \{\meta{subsection title}\}`;
+ \item subsubsection, via `\textsharp\textsharp\textsharp\textsharp{} \{\meta{subsubsection title}\}`;
+ \end{itemize}
+ \item If you wish to use the *numbered* version, write `\textsharp\textsharp+`, `\textsharp\textsharp\textsharp+` and `\textsharp\textsharp\textsharp\textsharp+` instead.
+ \end{itemize}
+
+ [Input/Include Files]
+ \begin{itemize}
+ \item Use `\textcolon\textcolon{} \{\meta{file name}\}` to input a file.
+ \item Use `\textcolon\textcolon\textcolon{} \{\meta{file name}\}` to include a file.
+ \end{itemize}
+
+ \medskip
+
+ And don't forget that you are still using \LaTeX, so images, tables and lists can be written as usual.
+
+
+##+ {Cautions}
+
+?
+ I see. Is there anything else for me to be careful about?
+
+:
+ Glad that you asked. Here are several things that should be taken care of:
+ \begin{itemize}
+ \item A question, answer or narration should always begin in a new paragraph.
+ \item An emphasized `enumerate` should also begin in a new paragraph. An emphasized `itemize` should usually begin in a new paragraph, with the exception that it can (partially) be used within an `enumerate`.
+ \item Likewise, a `section`/`subsection`/`subsubsection` should be placed in a separate paragraph.
+ \item Input or inclusion of files should also be operated in a separate paragraph.
+ \item For emphasizing and bolding the text, it would be necessary to separate the asterisks with~`\{\}` in some special cases: `\textasterisk\textasterisk like\textasterisk\textasterisk\{\}\textasterisk\textasterisk\textasterisk this\textasterisk\textasterisk\textasterisk\{\}\textasterisk one\textasterisk`.
+ \item Due to the recognition of the syntax, you cannot directly use characters like `\textasterisk` as usual, especially in math mode. You should consider using an alternative macro, such as `\textbackslash ast` for `\textasterisk` in math mode, or define a command version of the character in the preamble, such as `\textbackslash textasterisk` for `\textasterisk`. A list of predefined commands are:
+ \begin{itemize}
+ \item `\textbackslash textasterisk` for `\textasterisk`;
+ \item `\textbackslash textbacktick` for `\textbacktick`;
+ \item `\textbackslash textcolon` for `\textcolon`;
+ \item `\textbackslash textequalsign` for `\textequalsign`;
+ \item `\textbackslash textleftparen` for `\textleftparen`;
+ \item `\textbackslash textrightparen` for `\textrightparen`;
+ \item `\textbackslash textsharp` for `\textsharp`.
+ \item `\textbackslash textvert` for `\textvert`.
+ \end{itemize}
+ There are also a few that already provided by \LaTeX, such as:
+ \begin{itemize}
+ \item `\textbackslash textbackslash` for `\textbackslash`;
+ \item `\textbackslash textgreater` for `\textgreater`;
+ \item `\textbackslash textless` for `\textless`.
+ \end{itemize}
+ \end{itemize}
+
+
+##+ {Customization}
+
+?
+ Now that we have learned the basic usage, I would like to know more. Can I customize the interface to suit my preferences, for instance?
+
+:
+ Certainly. Apart from using themes via class option, you may also change the identifiers and the labels for each role in the conversation.
+
+ [Changing itentifiers]
+ Instead of the default identifiers, such as `?` for questions, you may also use your preferred one. This can be done via the use of `\textbackslash QASetTypePrefix` in the preamble of your document.
+ \begin{itemize}
+ \item Use `\textbackslash QASetTypePrefix\{Q\}\{\meta{identifiers}\}` to set the identifiers for questions.
+ \item Use `\textbackslash QASetTypePrefix\{A\}\{\meta{identifiers}\}` to set the identifiers for answers.
+ \item Use `\textbackslash QASetTypePrefix\{N\}\{\meta{identifiers}\}` to set the identifiers for narrations.
+ \end{itemize}
+ Here, \meta{identifier} is a comma list of your specified identifiers. For example, the default identifier for narrations is preset via `\textbackslash QASetTypePrefix\{N\}\{N:,",“,”,「\}`.
+ \QANote{Note that, due to its implementation, the identifier cannot contain comma `,` in it. If you wish to use an identifier that contains a comma, you may use `\textbackslash QAAddTypePrefix` instead, which only adds *one* identifier per use.}
+ \QANote{Note also that, the identifiers are *reset* upon changing of language. Thus, you need to put your setting into the corresponding language configuration, for example, via `\textbackslash AddLanguageSetting[\meta{language name}]\{\meta{settings}\}`}
+
+ [Changing labels]
+ You may also change the labels. For example, from the text \textquote{Q:} to a logo icon. This can be done via the use of `\textbackslash SetLogoCode` in the preamble of your document.
+ \begin{itemize}
+ \item Use `\textbackslash SetLogoCode\{Q\}\{\meta{logo code}\}` to set the labels for questions.
+ \item Use `\textbackslash SetLogoCode\{A\}\{\meta{logo code}\}` to set the labels for answers.
+ \end{itemize}
+ Here, \meta{logo code} is the actual code for displaying the corresponding label. For example, the default label for questions is preset via `\textbackslash SetLogoCode\{Q\}\{\textbackslash textbf\{Q\textbackslash,:\}\}`.
+ >>> In the demo document, you can find an example on how to use this command to specify a logo for each role in the conversation.
+
+
+##+ {Known Issues}
+
+?
+ Is there any known issue with this document class?
+
+:
+ Unfortunately, yes `:(`.
+
+ Below is a list of known issues:
+
+ \begin{itemize}
+ \item Currently, the code highlight is done by the package `listings`. Due to its own limitations, the result is still far from satisfactory. Using `minted` instead could improve the situation, but this would require `-shell-escape` and some external tweaking, thus it would still take some effort to make it work with the current document class.
+ % \item The code block containing long piece of code usually won't properly break across the page (which is essentially why this documentation and the demo documents enabled the `scroll` mode).
+ %% 2023-11-05, solved with the new option "answer outside the box".
+ \item Due to the current implementation, though it is already possible to automatically adopt the identifiers and labels for supported languages, you still need to use the identifiers `Q`, `A` and `N` when setting them.
+ \item Currently, for typesetting questions and answers, the text is in fact being put into some sort of `description` list. As a result, the level of lists might be slightly messed up, which could sometimes lead to issues with the list labels.
+ \end{itemize}
+
+
+##+ {Get Support}
+
+?
+ What should I do if I encounter any problem?
+
+:
+ If you run into any issues or have ideas for improvement, feel free to discuss on:
+ \begin{center}
+ \url{https://github.com/Jinwen-XU/Q-and-A/issues}
+ \end{center}
+ or email me via \href{mailto:ProjLib@outlook.com}{\texttt{ProjLib@outlook.com}}.
+
+
+\vspace{3\baselineskip}
+
+% ---
+
+% "
+% Below is the code of the current document.
+
+% == [latex] {\jobname.tex}
+
+\end{document}
diff --git a/macros/latex/contrib/q-and-a/doc/code/Q-and-A-doc-code-sample-content-result.pdf b/macros/latex/contrib/q-and-a/doc/code/Q-and-A-doc-code-sample-content-result.pdf
new file mode 100644
index 0000000000..1b5660f6b2
--- /dev/null
+++ b/macros/latex/contrib/q-and-a/doc/code/Q-and-A-doc-code-sample-content-result.pdf
Binary files differ
diff --git a/macros/latex/contrib/q-and-a/doc/code/Q-and-A-doc-code-sample-content-result.tex b/macros/latex/contrib/q-and-a/doc/code/Q-and-A-doc-code-sample-content-result.tex
new file mode 100644
index 0000000000..9323cc5037
--- /dev/null
+++ b/macros/latex/contrib/q-and-a/doc/code/Q-and-A-doc-code-sample-content-result.tex
@@ -0,0 +1,11 @@
+\documentclass[%11pt,
+ % scroll,
+]{Q-and-A}
+
+\geometry{paperwidth=12cm, paperheight=7.2cm}
+
+\begin{document}
+
+:: {Q-and-A-doc-code-sample-content}
+
+\end{document}
diff --git a/macros/latex/contrib/q-and-a/doc/code/Q-and-A-doc-code-sample-content.tex b/macros/latex/contrib/q-and-a/doc/code/Q-and-A-doc-code-sample-content.tex
new file mode 100644
index 0000000000..41ec0da73c
--- /dev/null
+++ b/macros/latex/contrib/q-and-a/doc/code/Q-and-A-doc-code-sample-content.tex
@@ -0,0 +1,21 @@
+Q:
+ What is `...`?
+
+A:
+ A `...` is a `...`. It has the following features:
+
+ [Feature A]
+ [*Aspect one] Firstly, ...
+ [*Aspect two] Secondly, ...
+
+ [Feature B]
+ It also ...
+
+Q:
+ Can you provide some examples for `...`?
+
+A:
+ Certainly. There are many types of `...`, for example:
+ [*] *emphasized*
+ [*] **bold**
+ [*] ***bold and emphasized*** \ No newline at end of file
diff --git a/macros/latex/contrib/q-and-a/doc/code/Q-and-A-doc-code-sample-document.tex b/macros/latex/contrib/q-and-a/doc/code/Q-and-A-doc-code-sample-document.tex
new file mode 100644
index 0000000000..7d4f6bc6ae
--- /dev/null
+++ b/macros/latex/contrib/q-and-a/doc/code/Q-and-A-doc-code-sample-document.tex
@@ -0,0 +1,14 @@
+\documentclass[%11pt,
+ use theme = (@@@\meta{theme}),
+ scroll,
+]{Q-A}
+
+\UseLanguage{(@@@\meta{language})} % For English this line can be omitted.
+
+\begin{document}
+
+
+% The content
+
+
+\end{document}