main
落雨楓 4 months ago
commit c764c94cc2

@ -0,0 +1 @@
The development of this software is covered by a [Code of Conduct](https://www.mediawiki.org/wiki/Special:MyLanguage/Code_of_Conduct).

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

@ -0,0 +1,27 @@
{
"require-dev": {
"mediawiki/mediawiki-codesniffer": "45.0.0",
"mediawiki/mediawiki-phan-config": "0.14.0",
"mediawiki/minus-x": "1.1.3",
"php-parallel-lint/php-console-highlighter": "1.0.0",
"php-parallel-lint/php-parallel-lint": "1.4.0"
},
"scripts": {
"fix": [
"minus-x fix .",
"phpcbf"
],
"test": [
"parallel-lint . --exclude vendor --exclude node_modules",
"@phpcs",
"minus-x check ."
],
"phan": "phan -d . --long-progress-bar",
"phpcs": "phpcs -sp --cache"
},
"config": {
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
}
}

@ -0,0 +1,77 @@
{
"name": "IsekaiTextExtracts",
"author": [
"Max Semenik"
],
"requires": {
"MediaWiki": ">= 1.43"
},
"url": "https://git.isekai.cn/hyperzlib/IsekaiTextExtracts",
"descriptionmsg": "textextracts-desc",
"license-name": "GPL-2.0-or-later",
"type": "other",
"ConfigRegistry": {
"textextracts": "GlobalVarConfig::newInstance"
},
"APIPropModules": {
"extracts": {
"class": "MediaWiki\\Extension\\TextExtracts\\ApiQueryExtracts",
"services": [
"ConfigFactory",
"MainWANObjectCache",
"LanguageConverterFactory",
"WikiPageFactory",
"TitleFormatter"
]
}
},
"MessagesDirs": {
"TextExtracts": [
"i18n",
"i18n/api"
]
},
"AutoloadNamespaces": {
"MediaWiki\\Extension\\TextExtracts\\": "includes/"
},
"Hooks": {
"ApiOpenSearchSuggest": "main",
"SearchResultProvideDescription": "main"
},
"HookHandlers": {
"main": {
"class": "MediaWiki\\Extension\\TextExtracts\\Hooks",
"services": [
"ConfigFactory"
]
}
},
"config": {
"ExtractsRemoveClasses": {
"value": [
"table",
"div",
"figure",
"script",
"input",
"style",
"ul.gallery",
".mw-editsection",
"sup.reference",
"ol.references",
".error",
".nomobile",
".noprint",
".noexcerpt",
".sortkey"
]
},
"ExtractsExtendOpenSearchXml": {
"value": false
},
"ExtractsExtendRestSearch": {
"value": false
}
},
"manifest_version": 2
}

@ -0,0 +1,21 @@
{
"@metadata": {
"authors": [
"ديفيد",
"Meno25"
]
},
"apihelp-query+extracts-summary": "يعرض نصا عاديا أو مقتطفات HTML محدودة من الصفحات المعينة.",
"apihelp-query+extracts-param-chars": "كم عدد شخصيات للعودة؟ قد يكون النص الفعلي المرتجع أطول قليلا.",
"apihelp-query+extracts-param-sentences": "كم عدد الجمل للعودة.",
"apihelp-query+extracts-param-limit": "كم عدد المقتطفات للعودة. (يمكن فقط إرجاع المقتطفات المتعددة إذا تم تعيين exintro إلى true.)",
"apihelp-query+extracts-param-intro": "إرجاع المحتوى فقط قبل القسم الأول.",
"apihelp-query+extracts-param-plaintext": "عودة ال مقتطفات كنص عادي بدلا من HTML محدود.",
"apihelp-query+extracts-param-sectionformat": "كيفية تنسيق الأقسام في وضع النص البسيط:",
"apihelp-query+extracts-example-1": "الحصول على استخراج 175 حرفا",
"apiwarn-textextracts-limit": "كان <var>exlimit</var> كبيرا جدا للحصول على طلب مقتطفات لمقالة بأكملها; انخفض إلى $1.",
"apiwarn-textextracts-unsupportedmodel": "يحتوي $1 على نموذج محتوى $2، وهو غير مدعوم; إرجاع مستخلص فارغ.",
"apiwarn-textextracts-title-in-file-namespace": "تم طلب استخراج عنوان في نطاق الملف، ولم يتم إرجاع أي شيء.",
"apiwarn-textextracts-sentences-and-html": "قد يحتوي الوسيط <var>$1sentences</var> على نتائج غير متوقعة عند استخدامها في وضع HTML.",
"apiwarn-textextracts-malformed-html": "قد يكون HTML غير صحيح و/أو غير متوازن وقد يحذف الصور المضمنة، استخدم على مسؤوليتك الخاصة. يتم سرد المشاكل المعروفة في https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TextExtracts#Caveats."
}

@ -0,0 +1,20 @@
{
"@metadata": {
"authors": [
"Xuacu"
]
},
"apihelp-query+extracts-summary": "Devuelve testu planu o estractos en HTML parciales de les páxines indicaes.",
"apihelp-query+extracts-param-chars": "Cuántos caráuteres hai que devolver. El testu real devueltu puede ser un poco más llargu.",
"apihelp-query+extracts-param-sentences": "Cuántes frases hai que devolver.",
"apihelp-query+extracts-param-limit": "Cuántos estractos van devolvese. (Sólo pueden devolvese estractos múltiples s'establez «exintro» como verdadero.)",
"apihelp-query+extracts-param-intro": "Devolver sólo el conteníu anterior a la primera seición.",
"apihelp-query+extracts-param-plaintext": "Devolver estractos como testu planu en llugar de HTML parcial.",
"apihelp-query+extracts-param-sectionformat": "Como dar formatu a les seiciones en mou testu planu:\n;plain:Sin formatu.\n;wiki:Formatu d'estilu testu wiki (== como esto ==).\n;raw:Representación interna d'esti módulu (títulos de sección prefixaos con &lt;ASCII 1&gt;&lt;ASCII 2&gt;&lt;nivel de seición&gt;&lt;ASCII 2&gt;&lt;ASCII 1&gt;).",
"apihelp-query+extracts-example-1": "Recibir un estractu de 175 caráuteres",
"apiwarn-textextracts-limit": "<var>exlimit</var> yera grande enforma pa una solicitú completa d'estractos del artículu, baxóse a $1.",
"apiwarn-textextracts-unsupportedmodel": "$1 tien el modelu de conteníu $2, que nun ye compatible; devolveráse un estractu vacíu.",
"apiwarn-textextracts-title-in-file-namespace": "Pidióse l'estractu d'un títulu del espaciu de nomes Ficheru, nun se devolvió nada.",
"apiwarn-textextracts-sentences-and-html": "El parámetru <var>$1sentences</var> puede tener resultaos inesperaos cuando s'usa en mou HTML.",
"apiwarn-textextracts-malformed-html": "El HTML puede tar mal escritu y/o nun tar equilibráu y puede omitir les imáxenes en llinia. Úsalu so la to responsabilidá. Los problemes conocíos recuéyense'n https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TextExtracts#Caveats."
}

@ -0,0 +1,24 @@
{
"@metadata": {
"authors": [
"Justman10000",
"Metalhead64"
]
},
"apihelp-query+extracts-summary": "Gibt den Klartext oder beschränkte HTML-Auszüge der angegebenen Seiten zurück.",
"apihelp-query+extracts-param-chars": "Wie viele Zeichen zurückgegeben werden sollen. Der tatsächlich zurückgegebene Text kann etwas länger sein.",
"apihelp-query+extracts-param-sentences": "Wie viele Sätze zurückgegeben werden sollen.",
"apihelp-query+extracts-param-limit": "Wie viele Auszüge zurückgegeben werden sollen (mehrere Auszüge können nur zurückgegeben werden, wenn exintro auf true gesetzt ist).",
"apihelp-query+extracts-param-intro": "Gibt nur den Inhalt vor dem ersten Abschnitt zurück.",
"apihelp-query+extracts-param-plaintext": "Gibt Auszüge als Klartext anstatt in beschränktem HTML zurück.",
"apihelp-query+extracts-param-sectionformat": "So formatierst du Abschnitte im Klartextmodus:",
"apihelp-query+extracts-paramvalue-sectionformat-plain": "Keine Formatierung.",
"apihelp-query+extracts-paramvalue-sectionformat-wiki": "Formatierung im Wikitext-Stil (== wie hier ==).",
"apihelp-query+extracts-paramvalue-sectionformat-raw": "Die interne Darstellung dieses Moduls (Abschnittstitel mit vorangestelltem &lt;ASCII 1&gt;&lt;ASCII 2&gt;&lt;Abschnittsebene&gt;&lt;ASCII 2&gt;&lt;ASCII 1&gt;).",
"apihelp-query+extracts-example-1": "Ruft einen 175-Zeichen-Auszug ab",
"apiwarn-textextracts-limit": "<var>exlimit</var> war zu groß für eine ganze Artikelauszugsabfrage, begrenzt auf $1.",
"apiwarn-textextracts-unsupportedmodel": "$1 hat das Inhaltsmodell $2, das nicht unterstützt wird. Es wird ein leerer Auszug zurückgegeben.",
"apiwarn-textextracts-title-in-file-namespace": "Es wurde ein Auszug für einen Titel im Dateinamensraum angefordert, jedoch wurde nichts zurückgegeben.",
"apiwarn-textextracts-sentences-and-html": "Der Parameter <var>$1sentences</var> könnte unerwartete Ergebnisse aufweisen, wenn er im HTML-Modus verwendet wird.",
"apiwarn-textextracts-malformed-html": "HTML könnte beschädigt und/oder unausgeglichen sein und Inline-Bilder weglassen. Verwendung auf eigene Gefahr. Bekannte Probleme sind unter https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TextExtracts#Caveats aufgelistet."
}

@ -0,0 +1,21 @@
{
"@metadata": {
"authors": []
},
"apihelp-query+extracts-summary": "Returns plain-text or limited HTML extracts of the given pages.",
"apihelp-query+extracts-param-chars": "How many characters to return. Actual text returned might be slightly longer.",
"apihelp-query+extracts-param-sentences": "How many sentences to return.",
"apihelp-query+extracts-param-limit": "How many extracts to return. (Multiple extracts can only be returned if exintro is set to true.)",
"apihelp-query+extracts-param-intro": "Return only content before the first section.",
"apihelp-query+extracts-param-plaintext": "Return extracts as plain text instead of limited HTML.",
"apihelp-query+extracts-param-sectionformat": "How to format sections in plaintext mode:",
"apihelp-query+extracts-paramvalue-sectionformat-plain": "No formatting.",
"apihelp-query+extracts-paramvalue-sectionformat-wiki": "Wikitext-style formatting (== like this ==).",
"apihelp-query+extracts-paramvalue-sectionformat-raw": "This module's internal representation (section titles prefixed with &lt;ASCII 1&gt;&lt;ASCII 2&gt;&lt;section level&gt;&lt;ASCII 2&gt;&lt;ASCII 1&gt;).",
"apihelp-query+extracts-example-1": "Get a 175-character extract",
"apiwarn-textextracts-limit": "<var>exlimit</var> was too large for a whole article extracts request, lowered to $1.",
"apiwarn-textextracts-unsupportedmodel": "$1 has content model $2, which is not supported; returning an empty extract.",
"apiwarn-textextracts-title-in-file-namespace": "Extract for a title in File namespace was requested, none returned.",
"apiwarn-textextracts-sentences-and-html": "The <var>$1sentences</var> parameter may have unexpected results when used in HTML mode.",
"apiwarn-textextracts-malformed-html": "HTML may be malformed and/or unbalanced and may omit inline images. Use at your own risk. Known problems are listed at https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TextExtracts#Caveats."
}

@ -0,0 +1,15 @@
{
"@metadata": {
"authors": [
"Dgstranz",
"Macofe"
]
},
"apihelp-query+extracts-param-chars": "Cuántos caracteres devolver. El texto real devuelto puede ser un poco más largo.",
"apihelp-query+extracts-param-sentences": "Cuántas oraciones se devolverán.",
"apihelp-query+extracts-param-limit": "Cuántos extractos se devolverán. (Los extractos múltiples sólo pueden devolverse si se estable 'exintro' como verdadero.)",
"apihelp-query+extracts-param-intro": "Devolver sólo el contenido antes de la primera sección.",
"apihelp-query+extracts-param-plaintext": "Devuelve extractos como texto sin formato en lugar de HTML limitado.",
"apihelp-query+extracts-example-1": "Obtener un extracto de 175 caracteres",
"apiwarn-textextracts-unsupportedmodel": "El modelo de contenido de $1 es $2, que no es compatible; se devolverá un extracto vacío."
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Ladsgroup"
]
},
"apihelp-query+extracts-param-sentences": "چند جمله بازگرداند."
}

@ -0,0 +1,29 @@
{
"@metadata": {
"authors": [
"Amire80",
"Gomoko",
"McDutchie",
"Thibaut120094",
"Urhixidur",
"Verdy p",
"Wladek92"
]
},
"apihelp-query+extracts-summary": "Renvoie des extraits en texte brut ou en HTML limité des pages données.",
"apihelp-query+extracts-param-chars": "Nombre de caractères à retourner. Le texte courant retourné peut être légèrement plus long.",
"apihelp-query+extracts-param-sentences": "Combien de phrases renvoyer.",
"apihelp-query+extracts-param-limit": "Combien dextraits à retourner (des extraits multiples peuvent être retournés si «exintro» est mis à «true»).",
"apihelp-query+extracts-param-intro": "Retourner uniquement le contenu précédant la première section.",
"apihelp-query+extracts-param-plaintext": "Retourner les extraits au format texte brut au lieu de HTML limité.",
"apihelp-query+extracts-param-sectionformat": "Comment mettre en forme les sections en mode texte brut:",
"apihelp-query+extracts-paramvalue-sectionformat-plain": "Pas de formatage.",
"apihelp-query+extracts-paramvalue-sectionformat-wiki": "Formatage de style Wikitext (== comme ceci ==).",
"apihelp-query+extracts-paramvalue-sectionformat-raw": "La représentation de ce module (section titres préfixée avec &lt;ASCII 1&gt;&lt;ASCII 2&gt;&lt;section level&gt;&lt;ASCII 2&gt;&lt;ASCII 1&gt;).",
"apihelp-query+extracts-example-1": "Obtenir un extrait de 175 caractères",
"apiwarn-textextracts-limit": "<var>exlimit</var> était trop grand pour une requête d'extraction d'article complet, réduit à $1.",
"apiwarn-textextracts-unsupportedmodel": "$1 a le modèle de contenu $2, qui nest pas pris en charge ; renvoi dun extrait vide.",
"apiwarn-textextracts-title-in-file-namespace": "Lextraction pour un titre dans lespace de noms Fichier a été demandée, rien na été renvoyé.",
"apiwarn-textextracts-sentences-and-html": "Le paramètre <var>$1sentences</var> peut avoir des résultats inattendus quand il est utilisé en mode HTML.",
"apiwarn-textextracts-malformed-html": "Le HTML peut être malformé ou non équilibré et peut omettre des images en ligne. À utiliser à vos risques et périls. Les problèmes connus sont listés sur https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TextExtracts#Caveats."
}

@ -0,0 +1,19 @@
{
"@metadata": {
"authors": [
"Banjo",
"Elisardojm"
]
},
"apihelp-query+extracts-summary": "Devolve texto plano ou extractos limitados en HTML das páxinas indicadas.",
"apihelp-query+extracts-param-chars": "Cantos caracteres devolver. O texto devolto actual pode ser un pouco máis longo.",
"apihelp-query+extracts-param-sentences": "Cantas frases devolver.",
"apihelp-query+extracts-param-limit": "Cantos extractos devolver. (Os extractos múltiples só se poden devolver se exintro ten valor ''true'', verdadeiro)",
"apihelp-query+extracts-param-intro": "Só devolver contido antes da primeira sección.",
"apihelp-query+extracts-param-plaintext": "Devolver extractos como texto plano no canto de HTML limitado.",
"apihelp-query+extracts-param-sectionformat": "Como formatear seccións en modo texto plano:\n;plain:Sen formato.\n;wiki:Formateo en estilo wiki (== como isto ==).\n;raw:Representación interna deste módulo (títulos de sección prefixados con &lt;ASCII 1&gt;&lt;ASCII 2&gt;&lt;nivel de sección&gt;&lt;ASCII 2&gt;&lt;ASCII 1&gt;).",
"apihelp-query+extracts-example-1": "Devolver un extracto de 175 caracteres",
"apiwarn-textextracts-limit": "<var>exlimit</var> era demasiado grande para unha petición de extracción do artigo completo, reducida a $1.",
"apiwarn-textextracts-unsupportedmodel": "$1 ten o modelo de contido $2, que non está soportado; devolvendo un extracto baleiro.",
"apiwarn-textextracts-title-in-file-namespace": "Pediuse un extracto para un título no espazo de nomes Ficheiro, non se obtivo ningún."
}

@ -0,0 +1,24 @@
{
"@metadata": {
"authors": [
"Amire80",
"Guycn2"
]
},
"apihelp-query+extracts-summary": "החזרת קטעים של הדפים הנתונים בטקסט רגיל או ב־HTML מוגבל.",
"apihelp-query+extracts-param-chars": "כמה תווים להחזיר. הטקסט האמתי עשוי להיות ארוך קצת יותר.",
"apihelp-query+extracts-param-sentences": "כמה משפטים להחזיר.",
"apihelp-query+extracts-param-limit": "כמה מובאות להחזיר. (מובאות מרובות יכולות להיות מוחזרות אם הערך של exintro הוא true.)",
"apihelp-query+extracts-param-intro": "להחזיר רק תוכן לפני הפרק הראשון.",
"apihelp-query+extracts-param-plaintext": "להחזיר מובאות בתור טקסט רגיל במקום HTML מוגבל.",
"apihelp-query+extracts-param-sectionformat": "איך לעצב פרקים במצב טקסט רגיל:",
"apihelp-query+extracts-paramvalue-sectionformat-plain": "ללא עיצוב.",
"apihelp-query+extracts-paramvalue-sectionformat-wiki": "עיצוב בסגנון קוד ויקי (== ככה ==).",
"apihelp-query+extracts-paramvalue-sectionformat-raw": "הייצוג הפנימי של המודול הזה (לכותרות פרקים תהיה תחילית &lt;ASCII 1&gt;&lt;ASCII 2&gt;&lt;section level&gt;&lt;ASCII 2&gt;&lt;ASCII 1&gt;).",
"apihelp-query+extracts-example-1": "קבלת מובאה של 175 תווים",
"apiwarn-textextracts-limit": "ה־<var>exlimit</var> היה גדול מדי בשביל בקשת מובאות מערך שלם, הונמך ל־$1.",
"apiwarn-textextracts-unsupportedmodel": "ל־$1 יש דגם תוכן $2, שאינו נתמך; מוחזרת מובאה ריקה.",
"apiwarn-textextracts-title-in-file-namespace": "נשלחה בקשה לקטע במרחב הקבצים, לא הוחזר דבר.",
"apiwarn-textextracts-sentences-and-html": "לפרמטר <var>$1sentences</var> עלולות להיות תוצאות בלתי־צפויות בעת שימוש במצב HTML.",
"apiwarn-textextracts-malformed-html": "ה־HTML עלול להיות פגום או בלתי־מאוזן, והוא עלול להשמיט תמונות מוטבעות. השימוש באפשרות זו הוא באחריותך. רשימה של בעיות ידועות מופיעה בדף https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TextExtracts#Caveats."
}

@ -0,0 +1,16 @@
{
"@metadata": {
"authors": [
"Tacsipacsi"
]
},
"apihelp-query+extracts-param-chars": "A visszaadandó karakterek száma. A tényleges visszaadott szöveg lehet valamivel hosszabb.",
"apihelp-query+extracts-param-sentences": "A visszaadandó mondatok száma.",
"apihelp-query+extracts-param-limit": "A visszaadandó kivonatok száma. (Több kivonat csak akkor adható vissza, ha az <var>exintro</var> meg van adva.)",
"apihelp-query+extracts-param-intro": "Csak az első szakasz előtti tartalom visszaadása.",
"apihelp-query+extracts-param-plaintext": "A kivonatok visszaadása egyszerű szövegként korlátozott HTML helyett.",
"apihelp-query+extracts-param-sectionformat": "A szakaszcímek formázása egyszerű szöveges módban:\n;plain: Nincs formázás.\n;wiki: Wikiszöveg-formázás (== így ==).\n;raw: Ezen modul belső reprezentációja (a szakaszcímek előtagja &lt;ASCII 1&gt;&lt;ASCII 2&gt;&lt;szakaszszint&gt;&lt;ASCII 2&gt;&lt;ASCII 1&gt;).",
"apihelp-query+extracts-example-1": "Egy 175 karakteres kivonat lekérése",
"apiwarn-textextracts-limit": "<var>exlimit</var> túl nagy teljes szócikk kivonatához, csökkentve $1 darabra.",
"apiwarn-textextracts-unsupportedmodel": "$1 tartalommodellje $2, ami nem támogatott; üres kivonat visszaadva."
}

@ -0,0 +1,23 @@
{
"@metadata": {
"authors": [
"McDutchie"
]
},
"apihelp-query+extracts-summary": "Restitue extractos del paginas date in forma de texto simple o HTML limitate.",
"apihelp-query+extracts-param-chars": "Quante characteres restituer. Le texto effectivemente restituite pote esser un poco plus longe.",
"apihelp-query+extracts-param-sentences": "Quante phrases restituer.",
"apihelp-query+extracts-param-limit": "Quante extractos restituer. (Plure extractos pote esser restituite solmente si <var>exintro</var> es mittite a <code>true</code> (ver).)",
"apihelp-query+extracts-param-intro": "Restituer solmente le contento ante le prime section.",
"apihelp-query+extracts-param-plaintext": "Restituer extractos in forma de texto simple in loco de HTML limitate.",
"apihelp-query+extracts-param-sectionformat": "Como formatar sectiones in modo de texto simple:",
"apihelp-query+extracts-paramvalue-sectionformat-plain": "Non formatar.",
"apihelp-query+extracts-paramvalue-sectionformat-wiki": "Formatar in stilo de wikitexto (== como isto ==).",
"apihelp-query+extracts-paramvalue-sectionformat-raw": "Usar le representation interne de iste modulo (titulos de section con prefixos &lt;ASCII 1&gt;&lt;ASCII 2&gt;&lt;nivello de section&gt;&lt;ASCII 2&gt;&lt;ASCII 1&gt;).",
"apihelp-query+extracts-example-1": "Obtener un extracto de 175 characteres",
"apiwarn-textextracts-limit": "<var>exlimit</var> esseva troppo grande pro un requesta de extractos de un articulo complete; reducite a $1.",
"apiwarn-textextracts-unsupportedmodel": "$1 ha le modello de contento $2, que non es supportate; se restitue un extracto vacue.",
"apiwarn-textextracts-title-in-file-namespace": "Un extracto pro un titulo in le spatio de nomines File ha essite requestate, nihil restituite.",
"apiwarn-textextracts-sentences-and-html": "Le parametro <var>$1sentences</var> pote producer resultatos inexpectate quando es usate in modo HTML.",
"apiwarn-textextracts-malformed-html": "Le codice HTML pote esser mal formate e/o non equilibrate e pote omitter imagines in linea. Usar a proprie risco. Le problemas cognoscite es listate sur https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TextExtracts#Caveats."
}

@ -0,0 +1,12 @@
{
"@metadata": {
"authors": [
"Beta16"
]
},
"apihelp-query+extracts-param-chars": "Quanti caratteri restituire. Il testo effettivo restituito potrebbe essere leggermente più lungo.",
"apihelp-query+extracts-param-sentences": "Quante frasi restituire.",
"apihelp-query+extracts-param-limit": "Quanti estratti restituire. (Più estratti possono essere restituiti solo se 'exintro' è impostato su 'true'.)",
"apihelp-query+extracts-param-intro": "Restituisci solo il contenuto prima della prima sezione.",
"apihelp-query+extracts-example-1": "Ottieni un estratto di 175 caratteri"
}

@ -0,0 +1,11 @@
{
"@metadata": {
"authors": [
"Yusuke1109"
]
},
"apihelp-query+extracts-summary": "指定されたページのプレーンテキストまたは制限付きHTMLを返します。",
"apihelp-query+extracts-param-chars": "返す文字数。返される実際の本文はわずかに長くなる場合があります。",
"apihelp-query+extracts-param-sentences": "返す文の数。",
"apihelp-query+extracts-param-intro": "最初の節の前の内容のみ返す。"
}

@ -0,0 +1,10 @@
{
"@metadata": {
"authors": [
"Ykhwong"
]
},
"apihelp-query+extracts-summary": "주어진 문서의 플레인 텍스트 또는 제한된 HTML 추출 정보를 반환합니다.",
"apiwarn-textextracts-sentences-and-html": "<var>$1sentences</var> 변수는 HTML 모드에서 사용할 때 예측하지 못한 결과가 있을 수 있습니다.",
"apiwarn-textextracts-malformed-html": "HTML이 잘못 구성되었거나 균형을 잃었거나 인라인 이미지가 누락된 상태일 수 있습니다. 자신의 책임 하에 사용하십시오. 알려진 문제는 [https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TextExtracts#Caveats 여기]에 나열되어 있습니다."
}

@ -0,0 +1,14 @@
{
"@metadata": {
"authors": [
"Purodha"
]
},
"apihelp-query+extracts-param-chars": "Wi vill Zeische ußjävve? Wat dann kütt, künnd e klei beßje länger sin.",
"apihelp-query+extracts-param-sentences": "Wi vell Säz ußjävve?",
"apihelp-query+extracts-param-limit": "Wi vell Ußzöhsch ußjävve?",
"apihelp-query+extracts-param-intro": "Jif blohß dat Schtök vör de eezde Övverschrevv uß.",
"apihelp-query+extracts-param-plaintext": "Donn Ußzöhsch als eijnfache Täx ußjävve, un nidd als bejränz <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"HyperText Markup Language\">HTML<i>.",
"apihelp-query+extracts-param-sectionformat": "Wi sulle Affschnedde em nommahle Täx ußjejovve wähde:\n;plain:Kein Fommahd.\n;wiki:Als Wikkitäx (== allsu esu ==).\n;raw:Heh däm Moduhl singe eije Aat (Övverschreffte met „&lt;ASCII 1&gt;&lt;ASCII 2&gt;&lt;de Ennröckong als Zahl&gt;&lt;ASCII 2&gt;&lt;ASCII 1&gt;“ dovör).",
"apihelp-query+extracts-example-1": "Holl ene Ußzoch met 175 Zeijsche dren."
}

@ -0,0 +1,23 @@
{
"@metadata": {
"authors": [
"Bjankuloski06"
]
},
"apihelp-query+extracts-summary": "Дава извадоци од дадените страници во прост текст или ограничен HTML.",
"apihelp-query+extracts-param-chars": "Колку знаци да има извадокот. Самиот текст што ќе се даде може да биде малку подолг.",
"apihelp-query+extracts-param-sentences": "Колку реченици да има извадокот.",
"apihelp-query+extracts-param-limit": "Колку извадоци да се дадат. (Ќе се дадат повеќе извадоци само exintro е наместен на true)",
"apihelp-query+extracts-param-intro": "Дај го само воведниот дел пред првиот оддел.",
"apihelp-query+extracts-param-plaintext": "Давај ги извадоците како прост текс или ограничен HTML.",
"apihelp-query+extracts-param-sectionformat": "Како да се форматираат одделите во прост текст:",
"apihelp-query+extracts-paramvalue-sectionformat-plain": "Без форматирање.",
"apihelp-query+extracts-paramvalue-sectionformat-wiki": "Викитекстуално форматирање (== вака ==).",
"apihelp-query+extracts-paramvalue-sectionformat-raw": "Внатрешната претстава на овој модул (насловите на одделните со претставка &lt;ASCII 1&gt;&lt;ASCII 2&gt;&lt;ниво на насловот&gt;&lt;ASCII 2&gt;&lt;ASCII 1&gt;).",
"apihelp-query+extracts-example-1": "Дај извадок во 175 знаци",
"apiwarn-textextracts-limit": "<var>exlimit</var> е преголемо за точно барање од цела статија. Го намалив на $1.",
"apiwarn-textextracts-unsupportedmodel": "$1 го има содржинскиот модел $2, кој не е поддржан. Давам празен извадок.",
"apiwarn-textextracts-title-in-file-namespace": "Беше побаран извадок за наслов во именскиот простор „Податотека“, но не добив ништо.",
"apiwarn-textextracts-sentences-and-html": "Параметарот <var>$1sentences</var> може да има неочекуван исход кога се користи во HTML-режим.",
"apiwarn-textextracts-malformed-html": "HTML може да е погрешно срочено и/или неурамнотежено, па затоа може да се изоставени слики во редовите. Користете го на сопствен ризик. Познатите проблеми се наведени на https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TextExtracts#Caveats."
}

@ -0,0 +1,24 @@
{
"@metadata": {
"authors": [
"Amire80",
"Jon Harald Søby"
]
},
"apihelp-query+extracts-summary": "Returnerer tekstutdrag fra de gitte sidene i rentekst eller begrenset HTML.",
"apihelp-query+extracts-param-chars": "Hvor mange tegn som skal returneres. Den faktiske teksten som returneres kan være litt lenger.",
"apihelp-query+extracts-param-sentences": "Hvor mange setninger som skal returneres.",
"apihelp-query+extracts-param-limit": "Hvor mange utdrag som skal returneres. (Flere utdrag kan kun returneres om exintro er satt til sann.)",
"apihelp-query+extracts-param-intro": "Returner kun innholdet foran første seksjon.",
"apihelp-query+extracts-param-plaintext": "Returner utdrag som ren tekst i stedet for HTML.",
"apihelp-query+extracts-param-sectionformat": "Hvordan seksjoner formateres i rentekstmodus:",
"apihelp-query+extracts-paramvalue-sectionformat-plain": "Ingen formatering.",
"apihelp-query+extracts-paramvalue-sectionformat-wiki": "Formatering i wikitekststil (== som dette ==).",
"apihelp-query+extracts-paramvalue-sectionformat-raw": "Denne modulens interne representasjon (seksjonstittel med prefiks &lt;ASCII 1&gt;&lt;ASCII 2&gt;&lt;section level&gt;&lt;ASCII 2&gt;&lt;ASCII 1&gt;).",
"apihelp-query+extracts-example-1": "Hent et utdrag på 175 tegn",
"apiwarn-textextracts-limit": "<var>exlimit</var> var for stor for en forespørsel om full artikkeluthenting, senket til $1.",
"apiwarn-textextracts-unsupportedmodel": "$1 har innholdsmodellen $2, som ikke støttes; returnerer en tom uthenting.",
"apiwarn-textextracts-title-in-file-namespace": "Utdrag for en tittel i filnavnerommet ble bedt om, ingen ble returnert.",
"apiwarn-textextracts-sentences-and-html": "Parameteren <var>$1sentences</var> kan ha uventede resultater om den brukes i HTML-modus.",
"apiwarn-textextracts-malformed-html": "HTML kan være misformet og/eller ubalansert, og kan utelate bilder. Bruk på egen risiko. Kjente problemer listes opp på https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TextExtracts#Caveats."
}

@ -0,0 +1,23 @@
{
"@metadata": {
"authors": [
"McDutchie"
]
},
"apihelp-query+extracts-summary": "Retourneert uittreksels van de opgegeven paginas in platte tekst of in beperkte HTML.",
"apihelp-query+extracts-param-chars": "Aantal te retourneren tekens. De daadwerkelijk geretourneerde tekst kan iets langer zijn.",
"apihelp-query+extracts-param-sentences": "Aantal te retourneren zinnen.",
"apihelp-query+extracts-param-limit": "Aantal te retourneren uittreksels. (Alleen als exintro op true staat kunnen meerdere uittreksels worden geretourneerd.)",
"apihelp-query+extracts-param-intro": "Alleen de inhoud vóór de eerste sectie retourneren.",
"apihelp-query+extracts-param-plaintext": "Uittreksels retourneren als platte tekst in plaats van beperkte HTML.",
"apihelp-query+extracts-param-sectionformat": "Opmaak van secties in platte-tekstmodus:",
"apihelp-query+extracts-paramvalue-sectionformat-plain": "Geen opmaak.",
"apihelp-query+extracts-paramvalue-sectionformat-wiki": "Opmaak in wikitekst-stijl (== zoals dit ==).",
"apihelp-query+extracts-paramvalue-sectionformat-raw": "De interne representatie van deze module (sectietitels voorafgegaan door &lt;ASCII 1&gt;&lt;ASCII 2&gt;&lt;sectieniveau&gt;&lt;ASCII 2&gt;&lt;ASCII 1&gt;).",
"apihelp-query+extracts-example-1": "Een uittreksel van 175 tekens opvragen",
"apiwarn-textextracts-limit": "<var>exlimit</var> was te groot om van een heel artikel uittreksels te maken en is verlaagd tot $1.",
"apiwarn-textextracts-unsupportedmodel": "$1 heeft inhoudsmodel $2, dat niet wordt ondersteund; er wordt een leeg uittreksel geretourneerd.",
"apiwarn-textextracts-title-in-file-namespace": "Er is een uittreksel voor een titel in de naamruimte Bestand (File) aangevraagd, maar er is er geen teruggestuurd.",
"apiwarn-textextracts-sentences-and-html": "De parameter <var>$1sentences</var> kan onverwachte resultaten opleveren bij gebruik in de HTML-modus.",
"apiwarn-textextracts-malformed-html": "De HTML-code is mogelijk verkeerd opgemaakt en/of onevenwichtig. Ingevoegde afbeeldingen kunnen eruit zijn weggelaten. Gebruik op eigen risico. Bekende problemen worden vermeld op https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TextExtracts#Caveats."
}

@ -0,0 +1,21 @@
{
"@metadata": {
"authors": [
"DeRudySoulStorm",
"SemanticPioneer"
]
},
"apihelp-query+extracts-summary": "Zwraca zwykły tekst lub fragmenty HTML podanych stron.",
"apihelp-query+extracts-param-chars": "Ile znaków ma zostać zwróconych. Rzeczywisty zwracany tekst może być nieco dłuższy.",
"apihelp-query+extracts-param-sentences": "Jak wiele zdań ma zostać zwróconych.",
"apihelp-query+extracts-param-limit": "Jak wiele fragmentów ma być zwróconych. (Wiele fragmentów może zostać zwróconych tylko wtedy, gdy parametr exintro ma wartość true).",
"apihelp-query+extracts-param-intro": "Zwróć tylko zawartość przed pierwszą sekcją.",
"apihelp-query+extracts-param-plaintext": "Zwróć fragmenty jako zwykły tekst zamiast ograniczonego kodu HTML.",
"apihelp-query+extracts-param-sectionformat": "Jak formatować sekcje w trybie zwykłego tekstu:\n;plain:Bez formatowania.\n;wiki:Formatowanie w stylu Wikitext (==jak to==).\n;raw:Wewnętrzna reprezentacja tego modułu (tytuły sekcji z prefiksem &lt;ASCII 1&gt;&lt;ASCII 2&gt;&lt;poziom sekcji&gt;&lt;ASCII 2&gt;&lt;ASCII 1&gt;).",
"apihelp-query+extracts-example-1": "Zdobądź 175-znakowy fragment",
"apiwarn-textextracts-limit": "Wartość <var>exlimit</var> była za duża dla żądania fragmentu z całego artykułu, obniżono do $1.",
"apiwarn-textextracts-unsupportedmodel": "$1 ma model zawartości $2, który nie jest obsługiwany; zwracam pusty fragment.",
"apiwarn-textextracts-title-in-file-namespace": "Zażądano wyodrębnienia tytułu z przestrzeni nazw plików, żaden nie został zwrócony.",
"apiwarn-textextracts-sentences-and-html": "Parametr <var>$1sentences</var> może mieć nieoczekiwane wyniki, jeśli jest używany w trybie HTML.",
"apiwarn-textextracts-malformed-html": "HTML może być zniekształcony i/lub niezrównoważony i może ominąć obrazy śród-liniowe. Używaj na własne ryzyko. Znane problemy są wymienione na stronie https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TextExtracts#Caveats."
}

@ -0,0 +1,24 @@
{
"@metadata": {
"authors": [
"!Silent",
"Araceletorres",
"Eduardo Addad de Oliveira",
"Eduardoaddad",
"Felipe L. Ewald"
]
},
"apihelp-query+extracts-summary": "Retorna texto simples ou extratos de HTML limitados das páginas dadas.",
"apihelp-query+extracts-param-chars": "Quantos caracteres retornar. O texto real retornado pode ser um pouco mais longo.",
"apihelp-query+extracts-param-sentences": "Quantas sentenças retornar.",
"apihelp-query+extracts-param-limit": "Quantos extratos retornar (múltiplos extratos somente podem ser retornados \"exintro\" estiver definido como verdadeiro).",
"apihelp-query+extracts-param-intro": "Retornar apenas o conteúdo antes da primeira seção.",
"apihelp-query+extracts-param-plaintext": "Retornar extratos como texto simples em vez de HTML limitado.",
"apihelp-query+extracts-param-sectionformat": "Como formatar as seções no modo de texto simples:\n;plain: sem formato\n;wiki: formato no estilo wiki (== dessa forma ==)\n;raw: representação interna deste módulo (títulos de seção prefixados com &lt;ASCII 1&gt;&lt;ASCII 2&gt;&lt;section level&gt;&lt;ASCII 2&gt;&lt;ASCII 1&gt;).",
"apihelp-query+extracts-example-1": "Obter um extrato de 175 caracteres",
"apiwarn-textextracts-limit": "<var>exlimit</var> foi muito grande para um pedido completo de extrato de artigo, reduzido para $1.",
"apiwarn-textextracts-unsupportedmodel": "$1 tem o modelo de conteúdo $2, que não é suportado; devolvendo um extrato vazio.",
"apiwarn-textextracts-title-in-file-namespace": "Foi solicitado um extrato para um título no espaço nominal do arquivo, nenhum retornou.",
"apiwarn-textextracts-sentences-and-html": "O parâmetro <var>$1sentences</var> pode gerar resultados inesperados quando é usado em modo HTML.",
"apiwarn-textextracts-malformed-html": "O HTML pode estar incorreto ou desequilibrado (ter etiquetas abertas e não fechadas) e pode omitir imagens em linha. Use por sua conta e risco. Os problemas conhecidos são listados em https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TextExtracts#Caveats."
}

@ -0,0 +1,20 @@
{
"@metadata": {
"authors": [
"Hamilton Abreu"
]
},
"apihelp-query+extracts-summary": "Fornece extratos do conteúdo das páginas indicadas, em texto simples ou HTML limitado.",
"apihelp-query+extracts-param-chars": "Quantos caracteres devem ser devolvidos. O texto devolvido pode ser ligeiramente mais longo.",
"apihelp-query+extracts-param-sentences": "Quantas frases devem ser devolvidas.",
"apihelp-query+extracts-param-limit": "Quantos extratos devem ser devolvidos. (Se pode ser devolvido mais do que um extrato se 'exintro' tiver o valor \"true\", verdadeiro).",
"apihelp-query+extracts-param-intro": "Devolver só o conteúdo antes da primeira secção.",
"apihelp-query+extracts-param-plaintext": "Devolver extratos em texto simples em vez de HTML limitado.",
"apihelp-query+extracts-param-sectionformat": "Como formatar as secções no modo de texto simples:\n;plain:Sem formatação.\n;wiki:Formatação ao estilo de texto wiki (== assim ==)\n;raw:A representação interna deste módulo (títulos de secção com os prefixos &lt;ASCII 1&gt;&lt;ASCII 2&gt;&lt;nível de secção&gt;&lt;ASCII 2&gt;&lt;ASCII 1&gt;).",
"apihelp-query+extracts-example-1": "Obter um extrato de 175 caracteres",
"apiwarn-textextracts-limit": "<var>exlimit</var> era demasiado grande para um pedido de extrato de um artigo completo; reduzido para $1.",
"apiwarn-textextracts-unsupportedmodel": "$1 tem o modelo de conteúdo $2, que não é suportado; a devolver um extrato vazio.",
"apiwarn-textextracts-title-in-file-namespace": "Foi pedido um extrato para um título no espaço nominal Ficheiro, não foi devolvido nenhum.",
"apiwarn-textextracts-sentences-and-html": "O parâmetro <var>$1sentences</var> pode gerar resultados inesperados quando é usado em modo HTML.",
"apiwarn-textextracts-malformed-html": "O HTML pode estar incorreto ou desequilibrado (ter etiquetas abertas e não fechadas) e pode omitir imagens em linha. Use por sua conta e risco. Os problemas conhecidos são listados em https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TextExtracts#Caveats."
}

@ -0,0 +1,23 @@
{
"@metadata": {
"authors": [
"Umherirrender"
]
},
"apihelp-query+extracts-summary": "{{doc-apihelp-summary|query+extracts}}",
"apihelp-query+extracts-param-chars": "{{doc-apihelp-param|query+extracts|chars}}",
"apihelp-query+extracts-param-sentences": "{{doc-apihelp-param|query+extracts|sentences}}",
"apihelp-query+extracts-param-limit": "{{doc-apihelp-param|query+extracts|limit}}",
"apihelp-query+extracts-param-intro": "{{doc-apihelp-param|query+extracts|intro}}",
"apihelp-query+extracts-param-plaintext": "{{doc-apihelp-param|query+extracts|plaintext}}",
"apihelp-query+extracts-param-sectionformat": "{{doc-apihelp-param|query+extracts|sectionformat}}",
"apihelp-query+extracts-paramvalue-sectionformat-plain": "{{doc-apihelp-paramvalue|query+extracts|sectionformat|plain}}",
"apihelp-query+extracts-paramvalue-sectionformat-wiki": "{{doc-apihelp-paramvalue|query+extracts|sectionformat|wiki}}",
"apihelp-query+extracts-paramvalue-sectionformat-raw": "{{doc-apihelp-paramvalue|query+extracts|sectionformat|raw}}",
"apihelp-query+extracts-example-1": "{{doc-apihelp-example|query+extracts}}",
"apiwarn-textextracts-limit": "{{doc-apierror}}\n\nParameters:\n* $1 - Limit that will be used",
"apiwarn-textextracts-unsupportedmodel": "{{doc-apierror}}\n\nParameters:\n* $1 - Page title\n* $2 - Content model",
"apiwarn-textextracts-title-in-file-namespace": "{{doc-apierror}}\n\nWarning message displayed when an extract for a title in File namespace is requested.",
"apiwarn-textextracts-sentences-and-html": "{{doc-apierror}}\n\nWarning message displayed documenting a known issue with sentence parameter used.",
"apiwarn-textextracts-malformed-html": "{{doc-apierror}}\n\nWarning message displayed documented known issues with the TextExtracts API."
}

@ -0,0 +1,23 @@
{
"@metadata": {
"authors": [
"Joetaras"
]
},
"apihelp-query+extracts-summary": "Dèje stuèzze jndr'à 'u teste semblice o HTML limitate da le pàggene specificate.",
"apihelp-query+extracts-param-chars": "Quanda carattere adda restituì. 'U teste de mò turnate pò essere 'nu picche cchiù luènghe.",
"apihelp-query+extracts-param-sentences": "Quanda frase adda turnà.",
"apihelp-query+extracts-param-limit": "Quanda stuèzze adda restituì. (Cchiù stuèzze ponne sulamende essere date ce exintro jè 'msotate a true.)",
"apihelp-query+extracts-param-intro": "Tuèrne sulamende 'u condenute apprime d'a prima selezione.",
"apihelp-query+extracts-param-plaintext": "Torne le stuèzze cumme teste semblice invece ca cumme HTML limitate.",
"apihelp-query+extracts-param-sectionformat": "Accume formattà le seziune jndr'à 'nu mode de teste semblice:",
"apihelp-query+extracts-paramvalue-sectionformat-plain": "Nisicuna formattazzione.",
"apihelp-query+extracts-paramvalue-sectionformat-wiki": "Formattazzione stile Uicchiteste (== cumme a quiste ==).",
"apihelp-query+extracts-paramvalue-sectionformat-raw": "Sta rappresendazione d'u module 'nderne (titole d'a sezione cu prefisse &lt;ASCII 1&gt;&lt;ASCII 2&gt;&lt;section level&gt;&lt;ASCII 2&gt;&lt;ASCII 1&gt;).",
"apihelp-query+extracts-example-1": "Pigghie 'nu stuèzze da 175 carattere",
"apiwarn-textextracts-limit": "<var>exlimit</var> jè troppe granne pa richieste de le stuèzze d'a vôsce, avasciate a $1.",
"apiwarn-textextracts-unsupportedmodel": "$1 ave 'nu modelle de condenute $2, 'u quale non g'è supportate; e dèje 'nu stuèzze vacande.",
"apiwarn-textextracts-title-in-file-namespace": "Ha state cercate 'n'estrazione pe 'nu titole jndr'à 'u namespace, no amme acchiate ninde.",
"apiwarn-textextracts-sentences-and-html": "'U parametre <var>$1sentences</var> pò avè resultate inaspettate quanne avène ausate cu 'u mode HTML.",
"apiwarn-textextracts-malformed-html": "HTML pò essere malformate e/o sbilangiate e pò zumbà le immaggine inline. Ce l'ause jè a rischie tune. Le probbleme canusciute so elengate sus a https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TextExtracts#Caveats."
}

@ -0,0 +1,21 @@
{
"@metadata": {
"authors": [
"Facenapalm",
"Okras"
]
},
"apihelp-query+extracts-summary": "Возвращает фрагменты указанных страниц в виде обычного текста или ограниченного HTML.",
"apihelp-query+extracts-param-chars": "Сколько символов возвращать. Возвращаемый в действительности текст может быть немного длиннее.",
"apihelp-query+extracts-param-sentences": "Сколько предложений возвращать.",
"apihelp-query+extracts-param-limit": "Сколько фрагментов возвращать. (Несколько фрагментов можно запрашивать только в том случае, если для exintro установлено значение true)",
"apihelp-query+extracts-param-intro": "Возвращаться только содержимое, идущее до первого раздела.",
"apihelp-query+extracts-param-plaintext": "Возвращать фрагменты в виде обычного текста вместо ограниченного HTML.",
"apihelp-query+extracts-param-sectionformat": "Как форматировать секции в режиме обычного текста:",
"apihelp-query+extracts-paramvalue-sectionformat-plain": "Без форматирования.",
"apihelp-query+extracts-paramvalue-sectionformat-wiki": "Вики-текстовое форматрирование (== вот так ==).",
"apihelp-query+extracts-paramvalue-sectionformat-raw": "Внутреннее представление данного модуля (перед названием секций будет &lt;ASCII 1&gt;&lt;ASCII 2&gt;&lt;уровень секции&gt;&lt;ASCII 2&gt;&lt;ASCII 1&gt;).",
"apihelp-query+extracts-example-1": "Получить 175-символьный фрагмент",
"apiwarn-textextracts-limit": "<var>exlimit</var> был слишком велик для запроса фрагмента всей статьи, поэтому он был снижен до $1.",
"apiwarn-textextracts-unsupportedmodel": "Модель содержимого $2, установленная для странице $1, не поддерживается; возвращён пустой фрагмент."
}

@ -0,0 +1,23 @@
{
"@metadata": {
"authors": [
"Eleassar"
]
},
"apihelp-query+extracts-summary": "Vrne golo besedilo ali omejene izvlečke HTML predloženih strani.",
"apihelp-query+extracts-param-chars": "Koliko znakov naj bo vrnjenih. Dejansko vrnjeno besedilo je lahko nekoliko daljše.",
"apihelp-query+extracts-param-sentences": "Koliko stavkov naj bo vrnjenih.",
"apihelp-query+extracts-param-limit": "Koliko izvlečkov naj bo vrnjenih (Več izvlečkov je mogoče vrniti le, če je »exintro« nastavljen na »true«.)",
"apihelp-query+extracts-param-intro": "Vrne samo vsebino pred prvim razdelkom.",
"apihelp-query+extracts-param-plaintext": "Vrne izvlečke kot navadno besedilo namesto omejenega HTML-ja.",
"apihelp-query+extracts-param-sectionformat": "Kako oblikovati razdelke v načinu navadnega besedila:",
"apihelp-query+extracts-paramvalue-sectionformat-plain": "Brez oblikovanja.",
"apihelp-query+extracts-paramvalue-sectionformat-wiki": "Oblikovanje v slogu vikibesedila (== tako ==).",
"apihelp-query+extracts-paramvalue-sectionformat-raw": "Notranja predstavitev tega modula (naslovi razdelkov s predpono &lt;ASCII 1&gt;&lt;ASCII 2&gt;&lt;section level&gt;&lt;ASCII 2&gt;&lt;ASCII 1&gt;).",
"apihelp-query+extracts-example-1": "Pridobite izvleček s 175 znaki",
"apiwarn-textextracts-limit": "<var>exlimit</var> je bil prevelik za zahtevek za izvlečke celotnega članka; zmanjšano na $1.",
"apiwarn-textextracts-unsupportedmodel": "$1 ima vsebinski model $2, ki ni podprt; vrnitev praznega izvlečka.",
"apiwarn-textextracts-title-in-file-namespace": "Zahtevan je bil izvleček za naslov v imenskem prostoru datotek; vrnjen ni bil noben.",
"apiwarn-textextracts-sentences-and-html": "Parameter <var>$1sentences</var> lahko vrne nepričakovane zadetke, če se uporablja v načinu HTML.",
"apiwarn-textextracts-malformed-html": "HTML je morda napačno oblikovan in/ali neuravnotežen in morda izpusti vstavljene slike. Uporabljajte na lastno odgovornost. Znane težave so navedene na https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TextExtracts#Caveats."
}

@ -0,0 +1,14 @@
{
"@metadata": {
"authors": [
"Kizule",
"Prevodim",
"Zoranzoki21"
]
},
"apihelp-query+extracts-summary": "Враћа сажетке датих страница у облику чистог текста или ограниченог HTML-а.",
"apihelp-query+extracts-param-chars": "Колико слова треба вратити. Текст који се заправо враћа може бити мало дужи.",
"apihelp-query+extracts-param-sentences": "Колико реченица треба вратити.",
"apihelp-query+extracts-param-intro": "Врати само садржај пре прве секције.",
"apiwarn-textextracts-unsupportedmodel": "$1 има модел садржаја $2, који није подржан; враћа се празан сажетак."
}

@ -0,0 +1,10 @@
{
"@metadata": {
"authors": []
},
"apihelp-query+extracts-summary": "Vraća sažetke datih stranica u obliku čistog teksta ili ograničenog HTML-a.",
"apihelp-query+extracts-param-chars": "Koliko slova treba vratiti. Tekst koji se zapravo vraća može biti malo duži.",
"apihelp-query+extracts-param-sentences": "Koliko rečenica treba vratiti.",
"apihelp-query+extracts-param-intro": "Vrati samo sadržaj pre prve sekcije.",
"apiwarn-textextracts-unsupportedmodel": "$1 ima model sadržaja $2, koji nije podržan; vraća se prazan sažetak."
}

@ -0,0 +1,21 @@
{
"@metadata": {
"authors": [
"Dhallin",
"Lokal Profil"
]
},
"apihelp-query+extracts-summary": "Returnerar ren text eller begränsade HTML-utdrag av de angivna sidorna.",
"apihelp-query+extracts-param-chars": "Antalet tecken att returnera. Den faktiska text som returneras kan vara något längre.",
"apihelp-query+extracts-param-sentences": "Antalet meningar som ska returneras.",
"apihelp-query+extracts-param-limit": "Hur många utdrag som ska returneras. (Flera extrakt kan endast returneras om exintro är satt till true.)",
"apihelp-query+extracts-param-intro": "Returnera bara innehåll före första avsnittet.",
"apihelp-query+extracts-param-plaintext": "Returnera extrakt som ren text eller begränsad HTML.",
"apihelp-query+extracts-param-sectionformat": "Hur stycken formateras i ren-text-läge:\n;plain:Ingen formatering.\n;wiki:Wikitext-stil formatering (== som detta ==).\n;raw:Denna moduls interna representation (avsnittstitlar med prefixet &lt;ASCII 1&gt;&lt;ASCII 2&gt;&lt;section level&gt;&lt;ASCII 2&gt;&lt;ASCII 1&gt;).",
"apihelp-query+extracts-example-1": "FÅ ett extrakt på 175 tecken",
"apiwarn-textextracts-limit": "<var>exlimit</var> var för stor för en begäran om hela artikelutdrag, sänkt till $1.",
"apiwarn-textextracts-unsupportedmodel": "$1 har innehållsmodell $2, som inte stöds; returnerar ett tomt utdrag.",
"apiwarn-textextracts-title-in-file-namespace": "Extrakt för en titel i filnamnutrymme begärdes, inget returnerades.",
"apiwarn-textextracts-sentences-and-html": "<var>$1sentences</var> Parametern kan ha oväntade resultat när den används i HTML-läge.",
"apiwarn-textextracts-malformed-html": "HTML kan vara missbildad och/eller obalanserad och kan utelämna inline bilder. Använd på egen risk. Kända problem listas på https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TextExtracts#Caveats."
}

@ -0,0 +1,21 @@
{
"@metadata": {
"authors": [
"BaRaN6161 TURK",
"SaldırganSincap"
]
},
"apihelp-query+extracts-summary": "Verilen sayfaların düz metin veya sınırlı HTML alıntılarını döndürür.",
"apihelp-query+extracts-param-chars": "Döndürülecek karakter sayısı. Döndürülen gerçek metin biraz daha uzun olabilir.",
"apihelp-query+extracts-param-sentences": "Geri döndürecek birçok cümle.",
"apihelp-query+extracts-param-limit": "Geri döndürecek alıntı. (Birden fazla alıntı yalnızca exintro true olarak ayarlanmışsa döndürülebilir.)",
"apihelp-query+extracts-param-intro": "Yalnızca ilk bölümden önceki içeriği döndürün.",
"apihelp-query+extracts-param-plaintext": "Özetleri sınırlı HTML yerine düz metin olarak döndürün.",
"apihelp-query+extracts-param-sectionformat": "Bölümleri düz metin modunda biçimlendirme:\n;plain:Biçimlendirme yok.\n;wiki:Vikimetin tarzı biçimlendirme (== bunun gibi ==).\n;raw:Bu modülün dahili gösterimi (&lt;ASCII 1&gt;&lt;ASCII 2&gt;&lt;bölüm düzeyi&gt;&lt;ASCII 2&gt;&lt;ASCII 1&gt; önekli bölüm başlıkları).",
"apihelp-query+extracts-example-1": "175 karakterlik bir alıntı edinin",
"apiwarn-textextracts-limit": "<var>exlimit</var>, tüm madde alıntıları isteği için çok büyüktü ve $1 düşürüldü.",
"apiwarn-textextracts-unsupportedmodel": "$1, desteklenmeyen $2 içerik modeline sahiptir; boş bir özü döndürme.",
"apiwarn-textextracts-title-in-file-namespace": "Dosya ad alanında bir başlık için ayıklama istendi, hiçbiri döndürülmedi.",
"apiwarn-textextracts-sentences-and-html": "<var>$1sentences</var> parametresi, HTML modunda kullanıldığında beklenmeyen sonuçlara sahip olabilir.",
"apiwarn-textextracts-malformed-html": "HTML hatalı biçimlendirilmiş ve/veya dengesiz olabilir ve satır içi resimleri atlayabilir. Kendi sorumluluğunuzdadır kullanın. Bilinen sorunlar https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TextExtracts#Caveats adresinde listelenmiştir."
}

@ -0,0 +1,24 @@
{
"@metadata": {
"authors": [
"Piramidion",
"Ата"
]
},
"apihelp-query+extracts-summary": "Видає звичайний текст або обмежені уривки HTML заданих сторінок.",
"apihelp-query+extracts-param-chars": "Скільки символів виводити. Дійсно виданий текст може бути дещо довшим.",
"apihelp-query+extracts-param-sentences": "Скільки речень виводити.",
"apihelp-query+extracts-param-limit": "Скільки уривків виводити. (Кілька уривків може виводитися, тільки якщо exintro має значення true.)",
"apihelp-query+extracts-param-intro": "Виводити лише вміст до першого розділу.",
"apihelp-query+extracts-param-plaintext": "Виводити уривки у вигляді звичайного тексту замість обмеженого HTML.",
"apihelp-query+extracts-param-sectionformat": "Як форматувати розділи у режимі звичайного тексту:",
"apihelp-query+extracts-paramvalue-sectionformat-plain": "Без форматування.",
"apihelp-query+extracts-paramvalue-sectionformat-wiki": "Форматування у вікістилі (== отак ==).",
"apihelp-query+extracts-paramvalue-sectionformat-raw": "Зовнішнє представлення цього модуля (назви розділів матимуть префікс &lt;ASCII 1&gt;&lt;ASCII 2&gt;&lt;section level&gt;&lt;ASCII 2&gt;&lt;ASCII 1&gt;).",
"apihelp-query+extracts-example-1": "Отримати 175-символьний уривок",
"apiwarn-textextracts-limit": "<var>exlimit</var> був надто великим для виконання запиту з видобування цілої статті; понижено до $1.",
"apiwarn-textextracts-unsupportedmodel": "$1 має контентну модель $2, яка не підтримується; повертаємо порожній витяг.",
"apiwarn-textextracts-title-in-file-namespace": "Подано запит на витяг для назви з простору назв Файл; не отримано нічого.",
"apiwarn-textextracts-sentences-and-html": "Параметр <var>$1sentences</var> може видати неочікувані результаті, якщо його використати в режимі HTML.",
"apiwarn-textextracts-malformed-html": "Код HTML може бути неправильно сформованим та/або незбалансованим і може пропускати вбудовані зображення. Використовуйте на свій власний ризик. Відомі проблеми перелічено на сторінці https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TextExtracts#Caveats."
}

@ -0,0 +1,27 @@
{
"@metadata": {
"authors": [
"GuoPC",
"LittlePaw365",
"Liuxinyu970226",
"Xiplus",
"Yfdyh000"
]
},
"apihelp-query+extracts-summary": "返回指定页面的纯文本或有限HTML格式摘录。",
"apihelp-query+extracts-param-chars": "返回字符数。实际返回的文本可能比这稍长。",
"apihelp-query+extracts-param-sentences": "返回句子数。",
"apihelp-query+extracts-param-limit": "返回摘录数。当exintro设为true时才能返回多段摘录。",
"apihelp-query+extracts-param-intro": "只返回首个章节前的内容。",
"apihelp-query+extracts-param-plaintext": "以纯文本而非有限HTML返回摘录。",
"apihelp-query+extracts-param-sectionformat": "纯文本模式下格式化章节方式:",
"apihelp-query+extracts-paramvalue-sectionformat-plain": "无格式。",
"apihelp-query+extracts-paramvalue-sectionformat-wiki": "wikitext样式的格式== 像这样 ==)。",
"apihelp-query+extracts-paramvalue-sectionformat-raw": "此模块的内部表示方法(章节标题前缀&lt;ASCII 1&gt;&lt;ASCII 2&gt;&lt;章节级别&gt;&lt;ASCII 2&gt;&lt;ASCII 1&gt;",
"apihelp-query+extracts-example-1": "获取175个字符的摘录",
"apiwarn-textextracts-limit": "<var>exlimit</var>对于完整条目摘录请求而言过大,已降低为$1。",
"apiwarn-textextracts-unsupportedmodel": "$1有不受支持的内容模型$2将返回空摘录。",
"apiwarn-textextracts-title-in-file-namespace": "请求了文件命名空间内标题的摘录,因此没有返回。",
"apiwarn-textextracts-sentences-and-html": "当用在HTML模式时<var>$1sentences</var>参数可能有意外结果。",
"apiwarn-textextracts-malformed-html": "HTML可能有缺陷和/或不稳定并可能忽略行内图片。使用时请自行承担风险。已知问题在https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TextExtracts#Caveats列出。"
}

@ -0,0 +1,23 @@
{
"@metadata": {
"authors": [
"Kly"
]
},
"apihelp-query+extracts-summary": "回傳純文字或受限的指定頁面 HTML 匯出。",
"apihelp-query+extracts-param-chars": "要回傳的字元數量。實際回傳的文字可能會稍多。",
"apihelp-query+extracts-param-sentences": "要回傳的文句數量。",
"apihelp-query+extracts-param-limit": "要回傳的匯出數量。(若 exintro 設定成 true 可回傳多個提取。)",
"apihelp-query+extracts-param-intro": "僅回傳在首個段落前的內容。",
"apihelp-query+extracts-param-plaintext": "回傳匯出為純文字而非受限的 HTML 內容",
"apihelp-query+extracts-param-sectionformat": "在純文字模式如何格式化段落:",
"apihelp-query+extracts-paramvalue-sectionformat-plain": "無格式。",
"apihelp-query+extracts-paramvalue-sectionformat-wiki": "Wikitext 樣式格式(== 例如像這樣 ==)。",
"apihelp-query+extracts-paramvalue-sectionformat-raw": "此模組的內建呈現方法(帶有 &lt;ASCII 1&gt;&lt;ASCII 2&gt;&lt;段落層級&gt;&lt;ASCII 2&gt;&lt;ASCII 1&gt; 的段落標題前綴)。",
"apihelp-query+extracts-example-1": "取得 175-字元匯出內容",
"apiwarn-textextracts-limit": "<var>exlimit</var> 對於整個條目提取請求太大,已降為 $1。",
"apiwarn-textextracts-unsupportedmodel": "$1 含有內容模組 $2這並不被支援且會回傳空白匯出內容。",
"apiwarn-textextracts-title-in-file-namespace": "已請求匯出在檔案命名空間的標題,但未有內容回傳。",
"apiwarn-textextracts-sentences-and-html": "當使用 HTML 模式時,<var>$1sentences</var> 參數可能會產生預期外的結果。",
"apiwarn-textextracts-malformed-html": "HTML 可能不完整/或不穩定,並可能會忽略行內的圖片。使用時請自行承擔風險。已知問題則列在 https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TextExtracts#Caveats 裡。"
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"ديفيد"
]
},
"textextracts-desc": "يوفر نصا عاديا أو مقتطفات HTML محدودة من محتوى الصفحة"
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Xuacu"
]
},
"textextracts-desc": "Ufre estractos del conteníu de la páxina en testu simple o HTML llimitáu"
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Умар"
]
},
"textextracts-desc": "АгӀонийн чулацаман дешнаш лата до йозан йа HTML-форматехь"
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Mormegil"
]
},
"textextracts-desc": "Poskytuje extrakty obsahu stránky v čistém textu nebo omezeném HTML"
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Metalhead64"
]
},
"textextracts-desc": "Stellt Auszüge aus Seiten in Klartext oder beschränktem HTML zur Verfügung"
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Michawiki"
]
},
"textextracts-desc": "Staja wupise wopsimjeśa boka w lutnem teksće abo wobgranicowanem HTML k dispoziciji"
}

@ -0,0 +1,6 @@
{
"@metadata": {
"authors": []
},
"textextracts-desc": "Provides plain-text or limited HTML extracts of page content"
}

@ -0,0 +1,10 @@
{
"@metadata": {
"authors": [
"Dgstranz",
"Fitoschido",
"Macofe"
]
},
"textextracts-desc": "Proporciona extractos del contenido de una página en texto sencillo o HTML limitado"
}

@ -0,0 +1,9 @@
{
"@metadata": {
"authors": [
"Armin1392",
"Ladsgroup"
]
},
"textextracts-desc": "ارائه متن ساده یا اچ‌تی‌ام‌ال محدود شده، محتوای صفحه را بیرون می‌کشد"
}

@ -0,0 +1,11 @@
{
"@metadata": {
"authors": [
"Gomoko",
"Thibaut120094",
"Urhixidur",
"Wladek92"
]
},
"textextracts-desc": "Fournit des extraits en texte brut ou en HTML limité du contenu de la page"
}

@ -0,0 +1,10 @@
{
"@metadata": {
"authors": [
"Banjo",
"Elisardojm",
"Toliño"
]
},
"textextracts-desc": "Proporciona extractos de texto do contido da páxina sen formato ou con HTML limitado"
}

@ -0,0 +1,9 @@
{
"@metadata": {
"authors": [
"Amire80",
"Guycn2"
]
},
"textextracts-desc": "אספקת מובאות של תוכן הדפים טקסט בפשוט או ב־HTML מוגבל"
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Michawiki"
]
},
"textextracts-desc": "Staja wupisy wobsaha strony w lutym teksće abo wobmjezowanym HTML k dispoziciji"
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Tacsipacsi"
]
},
"textextracts-desc": "Egy lap tartalmának egyszerű szöveges vagy korlátozott HTML kivonatát készíti el"
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"McDutchie"
]
},
"textextracts-desc": "Forni extractos del contento de paginas in forma de texto simple o HTML limitate"
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Daud I.F. Argana"
]
},
"textextracts-desc": "Menyediakan ekstrak teks polos atau HTML terbatas dari konten halaman"
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Beta16"
]
},
"textextracts-desc": "Fornisce estratti in testo semplice o HTML dal contenuto della pagina"
}

@ -0,0 +1,9 @@
{
"@metadata": {
"authors": [
"Shirayuki",
"Yusuke1109"
]
},
"textextracts-desc": "ページ本文を抽出したプレーンテキストまたは制限付き HTML を提供する"
}

@ -0,0 +1,9 @@
{
"@metadata": {
"authors": [
"Priviet",
"Ykhwong"
]
},
"textextracts-desc": "문서 내용을 추출한 일반 텍스트나 제한된 HTML을 제공"
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Purodha"
]
},
"textextracts-desc": "Määt bejränz Ußzööje vun Sigge em HTML udder als Täx möjjelesch."
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Bjankuloski06"
]
},
"textextracts-desc": "Дава извадоци од содржината на страницата во прост текст или ограничен HTML"
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Praveenp"
]
},
"textextracts-desc": "താളിന്റെ ഉള്ളടക്കം വെറും-എഴുത്തായോ, ഭാഗികമായി എച്ച്.റ്റി.എം.എൽ. ആയോ എടുക്കൽ അനുവദിക്കുന്നു"
}

@ -0,0 +1,9 @@
{
"@metadata": {
"authors": [
"Danmichaelo",
"Jon Harald Søby"
]
},
"textextracts-desc": "Tilbyr et kort utdrag av sideinnholdet som ren tekst eller begrenset HTML"
}

@ -0,0 +1,10 @@
{
"@metadata": {
"authors": [
"Arent",
"McDutchie",
"Siebrand"
]
},
"textextracts-desc": "Maakt uittreksels van pagina-inhoud in platte tekst of in beperkte HTML"
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Cedric31"
]
},
"textextracts-desc": "Provesís d'extraits en tèxte brut o en HTML limitat del contengut de la pagina"
}

@ -0,0 +1,10 @@
{
"@metadata": {
"authors": [
"DeRudySoulStorm",
"Rail",
"Railfail536"
]
},
"textextracts-desc": "Wprowadza wyodrębnianie czystego tekstu, lub pewnych elementów HTML z zawartości strony"
}

@ -0,0 +1,11 @@
{
"@metadata": {
"authors": [
"!Silent",
"Araceletorres",
"Eduardo Addad de Oliveira",
"Felipe L. Ewald"
]
},
"textextracts-desc": "Fornece texto simples ou extratos de HTML limitados de conteúdo da página"
}

@ -0,0 +1,10 @@
{
"@metadata": {
"authors": [
"Hamilton Abreu",
"Waldir",
"Waldyrious"
]
},
"textextracts-desc": "Fornece extratos do conteúdo de páginas em texto simples ou HTML limitado"
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Umherirrender"
]
},
"textextracts-desc": "{{desc|name=TextExtracts|url=https://www.mediawiki.org/wiki/Extension:TextExtracts}}"
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Joetaras"
]
},
"textextracts-desc": "Dèje stuèzze jndr'à 'u teste semblice o HTML da 'u condenute d'a pàgene"
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Okras"
]
},
"textextracts-desc": "Предоставляет фрагмент содержимого страниц в текстовом или ограниченном HTML-формате"
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Ajeje Brazorf"
]
},
"textextracts-desc": "Furnisci stratti n testu sìmpruci o HTML dû cuntinutu dâ pàggina"
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Eleassar"
]
},
"textextracts-desc": "Zagotavlja izvlečke vsebine strani v navadnem besedilu ali omejenem jeziku HTML"
}

@ -0,0 +1,9 @@
{
"@metadata": {
"authors": [
"Prevodim",
"Zoranzoki21"
]
},
"textextracts-desc": "Пружа сажетак садржаја странице у облику чистог текста или ограниченог HTML-а"
}

@ -0,0 +1,6 @@
{
"@metadata": {
"authors": []
},
"textextracts-desc": "Pruža sažetak sadržaja stranice u obliku čistog teksta ili ograničenog HTML-a"
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Lokal Profil"
]
},
"textextracts-desc": "Erbjuder extrakt, i oformaterad text eller begränsad HTML, av sidinnehåll"
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"BaRaN6161 TURK"
]
},
"textextracts-desc": "Sayfa içeriğinin düz metin veya sınırlı HTML özetini sağlar"
}

@ -0,0 +1,10 @@
{
"@metadata": {
"authors": [
"Andriykopanytsia",
"Piramidion",
"Ата"
]
},
"textextracts-desc": "Забезпечує видобування звичайного текст або обмеженого HTML із вмісту сторінки"
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Minh Nguyen"
]
},
"textextracts-desc": "Tóm lược nội dung trang dưới dạng văn bản thuần hoặc HTML đơn giản"
}

@ -0,0 +1,9 @@
{
"@metadata": {
"authors": [
"Liuxinyu970226",
"Yfdyh000"
]
},
"textextracts-desc": "提供纯文本或有限的HTML页面内容提取"
}

@ -0,0 +1,8 @@
{
"@metadata": {
"authors": [
"Kly"
]
},
"textextracts-desc": "提供純文字或受限的頁面內容 HTML 匯出"
}

@ -0,0 +1,408 @@
<?php
namespace MediaWiki\Extension\TextExtracts;
use MediaWiki\Api\ApiBase;
use MediaWiki\Api\ApiQuery;
use MediaWiki\Api\ApiQueryBase;
use MediaWiki\Api\ApiUsageException;
use MediaWiki\Config\Config;
use MediaWiki\Config\ConfigFactory;
use MediaWiki\Languages\LanguageConverterFactory;
use MediaWiki\Logger\LoggerFactory;
use MediaWiki\MediaWikiServices;
use MediaWiki\Page\PageIdentity;
use MediaWiki\Page\WikiPageFactory;
use MediaWiki\Parser\ParserOptions;
use MediaWiki\Title\TitleFormatter;
use Wikimedia\ObjectCache\WANObjectCache;
use Wikimedia\ParamValidator\ParamValidator;
use WikiPage;
/**
* @license GPL-2.0-or-later
*/
class ApiQueryExtracts extends ApiQueryBase {
/**
* Bump when memcache needs clearing
*/
private const CACHE_VERSION = 2;
private const PREFIX = 'ex';
/**
* @var array
*/
private $params;
/**
* @var Config
*/
private $config;
/**
* @var WANObjectCache
*/
private $cache;
/**
* @var LanguageConverterFactory
*/
private $langConvFactory;
/**
* @var WikiPageFactory
*/
private $wikiPageFactory;
private TitleFormatter $titleFormatter;
// TODO: Allow extensions to hook into this to opt-in.
// This is partly for security reasons; see T107170.
/**
* @var string[]
*/
private $supportedContentModels = [ 'wikitext' ];
/**
* @param ApiQuery $query API query module object
* @param string $moduleName Name of this query module
* @param ConfigFactory $configFactory
* @param WANObjectCache $cache
* @param LanguageConverterFactory $langConvFactory
* @param WikiPageFactory $wikiPageFactory
* @param TitleFormatter $titleFormatter
*/
public function __construct(
$query,
$moduleName,
ConfigFactory $configFactory,
WANObjectCache $cache,
LanguageConverterFactory $langConvFactory,
WikiPageFactory $wikiPageFactory,
TitleFormatter $titleFormatter
) {
parent::__construct( $query, $moduleName, self::PREFIX );
$this->config = $configFactory->makeConfig( 'textextracts' );
$this->cache = $cache;
$this->langConvFactory = $langConvFactory;
$this->wikiPageFactory = $wikiPageFactory;
$this->titleFormatter = $titleFormatter;
}
/**
* Evaluates the parameters, performs the requested extraction of text,
* and sets up the result
*/
public function execute() {
$titles = $this->getPageSet()->getGoodPages();
if ( $titles === [] ) {
return;
}
$isXml = $this->getMain()->isInternalMode()
|| $this->getMain()->getPrinter()->getFormat() == 'XML';
$result = $this->getResult();
$params = $this->params = $this->extractRequestParams();
$this->requireMaxOneParameter( $params, 'chars', 'sentences' );
$continue = 0;
$limit = intval( $params['limit'] );
if ( $limit > 1 && !$params['intro'] && count( $titles ) > 1 ) {
$limit = 1;
$this->addWarning( [ 'apiwarn-textextracts-limit', $limit ] );
}
if ( isset( $params['continue'] ) ) {
$continue = intval( $params['continue'] );
$this->dieContinueUsageIf( $continue < 0 || $continue > count( $titles ) );
$titles = array_slice( $titles, $continue, null, true );
}
$count = 0;
$titleInFileNamespace = false;
/** @var PageIdentity $t */
foreach ( $titles as $id => $t ) {
if ( ++$count > $limit ) {
$this->setContinueEnumParameter( 'continue', $continue + $count - 1 );
break;
}
if ( $t->getNamespace() === NS_FILE ) {
$text = '';
$titleInFileNamespace = true;
} else {
$params = $this->params;
$text = $this->getExtract( $t );
$text = $this->truncate( $text );
if ( $params['plaintext'] ) {
$text = $this->doSections( $text );
} else {
if ( $params['sentences'] ) {
$this->addWarning( $this->msg( 'apiwarn-textextracts-sentences-and-html', self::PREFIX ) );
}
$this->addWarning( 'apiwarn-textextracts-malformed-html' );
}
}
if ( $isXml ) {
$fit = $result->addValue( [ 'query', 'pages', $id ], 'extract', [ '*' => $text ] );
} else {
$fit = $result->addValue( [ 'query', 'pages', $id ], 'extract', $text );
}
if ( !$fit ) {
$this->setContinueEnumParameter( 'continue', $continue + $count - 1 );
break;
}
}
if ( $titleInFileNamespace ) {
$this->addWarning( 'apiwarn-textextracts-title-in-file-namespace' );
}
}
/**
* @param array $params Ignored parameters
* @return string
*/
public function getCacheMode( $params ) {
return 'public';
}
/**
* Returns a processed, but not trimmed extract
* @param PageIdentity $title
* @return string
*/
private function getExtract( PageIdentity $title ) {
$page = $this->wikiPageFactory->newFromTitle( $title );
$contentModel = $page->getContentModel();
if ( !in_array( $contentModel, $this->supportedContentModels, true ) ) {
$this->addWarning( [
'apiwarn-textextracts-unsupportedmodel',
wfEscapeWikiText( $this->titleFormatter->getPrefixedText( $title ) ),
$contentModel
] );
return '';
}
$introOnly = $this->params['intro'];
$text = false; // $this->getFromCache( $page, $introOnly );
// if we need just first section, try retrieving full page and getting first section out of it
if ( $text === false && $introOnly ) {
$text = false; // $this->getFromCache( $page, false );
if ( $text !== false ) {
$text = $this->getFirstSection( $text, $this->params['plaintext'] );
}
}
if ( $text === false ) {
$text = $this->parse( $page );
$text = $this->convertText( $text );
$this->setCache( $page, $text );
}
return $text;
}
/**
* @param WANObjectCache $cache
* @param WikiPage $page
* @param bool $introOnly
* @return string
*/
private function cacheKey( WANObjectCache $cache, WikiPage $page, $introOnly ) {
$langConv = $this->langConvFactory->getLanguageConverter( $page->getTitle()->getPageLanguage() );
return $cache->makeKey( 'textextracts', self::CACHE_VERSION,
$page->getId(), $page->getTouched(),
$langConv->getPreferredVariant(),
$this->params['plaintext'] ? 'plaintext' : 'html',
$introOnly ? 'intro' : 'full'
);
}
/**
* @param WikiPage $page
* @param bool $introOnly
* @return string|false
*/
private function getFromCache( WikiPage $page, $introOnly ) {
$cache = $this->cache;
// @TODO: replace with getWithSetCallback()
$key = $this->cacheKey( $cache, $page, $introOnly );
return $cache->get( $key );
}
/**
* @param WikiPage $page
* @param string $text
*/
private function setCache( WikiPage $page, $text ) {
$cache = $this->cache;
// @TODO: replace with getWithSetCallback()
$key = $this->cacheKey( $cache, $page, $this->params['intro'] );
$cache->set( $key, $text, $this->getConfig()->get( 'ParserCacheExpireTime' ) );
}
/**
* @param string $text
* @param bool $plainText
* @return string
*/
private function getFirstSection( $text, $plainText ) {
// Remove headers
if ( $plainText ) {
$text = preg_replace( '/^(<h[1-6][^>]*>.*?<\/h[1-6]>|\n)*/s', '', $text );
} else {
$text = preg_replace( '/^(<h[1-6][^>]*>.*?<\/h[1-6]>|\n)*/s', '', $text );
}
if ( $plainText ) {
$regexp = '/^.*?(?=' . ExtractFormatter::SECTION_MARKER_START .
'(?!.' . ExtractFormatter::SECTION_MARKER_END . '<h2 id="mw-toc-heading"))/s';
} else {
$regexp = '/^.*?(?=<h[1-6]\b(?! id="mw-toc-heading"))/s';
}
if ( preg_match( $regexp, $text, $matches ) ) {
$text = $matches[0];
}
return $text;
}
/**
* Returns page HTML
* @param WikiPage $page
* @return string
* @throws ApiUsageException
*/
private function parse( WikiPage $page ) {
$parserOutputAccess = MediaWikiServices::getInstance()->getParserOutputAccess();
$status = $parserOutputAccess->getParserOutput(
$page->toPageRecord(),
ParserOptions::newFromAnon()
);
if ( $status->isOK() ) {
$pout = $status->getValue();
$text = $pout->getText( [ 'unwrap' => true ] );
if ( $this->params['intro'] ) {
$text = $this->getFirstSection( $text, false );
}
return $text;
} else {
LoggerFactory::getInstance( 'textextracts' )->warning(
'Parse attempt failed while generating text extract', [
'title' => $page->getTitle()->getFullText(),
'url' => $this->getRequest()->getFullRequestURL(),
'reason' => $status->getWikiText( false, false, 'en' )
] );
$this->dieStatus( $status );
}
}
/**
* Converts page HTML into an extract
* @param string $text
* @return string
*/
private function convertText( $text ) {
$fmt = new ExtractFormatter( $text, $this->params['plaintext'] );
$fmt->remove( $this->config->get( 'ExtractsRemoveClasses' ) );
$text = $fmt->getText();
return $text;
}
/**
* Truncate the given text to a certain number of characters or sentences
* @param string $text The text to truncate
* @return string
*/
private function truncate( $text ) {
$useTidy = !$this->params['plaintext'];
$truncator = new TextTruncator( $useTidy );
if ( $this->params['chars'] ) {
$truncatedText = $truncator->getFirstChars( $text, $this->params['chars'] );
if ( $truncatedText !== $text ) {
$text = $truncatedText . $this->msg( 'ellipsis' )->text();
}
} elseif ( $this->params['sentences'] ) {
$text = $truncator->getFirstSentences( $text, $this->params['sentences'] );
}
return $text;
}
/**
* @param string $text
* @return string
*/
private function doSections( $text ) {
$pattern = '/' .
ExtractFormatter::SECTION_MARKER_START . '(\d)' .
ExtractFormatter::SECTION_MARKER_END . '(.*)/';
switch ( $this->params['sectionformat'] ) {
case 'raw':
return $text;
case 'wiki':
return preg_replace_callback( $pattern, static function ( $matches ) {
$bars = str_repeat( '=', $matches[1] );
return "\n$bars " . trim( $matches[2] ) . " $bars";
}, $text );
case 'plain':
return preg_replace_callback( $pattern, static function ( $matches ) {
return "\n" . trim( $matches[2] );
}, $text );
default:
throw new \LogicException( 'Invalid sectionformat' );
}
}
/**
* @inheritDoc
*/
public function getAllowedParams() {
return [
'chars' => [
ApiBase::PARAM_TYPE => 'integer',
ApiBase::PARAM_MIN => 1,
ApiBase::PARAM_MAX => 1200,
],
'sentences' => [
ApiBase::PARAM_TYPE => 'integer',
ApiBase::PARAM_MIN => 1,
ApiBase::PARAM_MAX => 10,
],
'limit' => [
ParamValidator::PARAM_DEFAULT => 20,
ApiBase::PARAM_TYPE => 'limit',
ApiBase::PARAM_MIN => 1,
ApiBase::PARAM_MAX => 20,
ApiBase::PARAM_MAX2 => 20,
],
'intro' => false,
'plaintext' => false,
'sectionformat' => [
ApiBase::PARAM_TYPE => [ 'plain', 'wiki', 'raw' ],
ParamValidator::PARAM_DEFAULT => 'wiki',
ApiBase::PARAM_HELP_MSG_PER_VALUE => [],
],
'continue' => [
ApiBase::PARAM_TYPE => 'integer',
ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
],
];
}
/**
* @inheritDoc
*/
protected function getExamplesMessages() {
return [
'action=query&prop=extracts&exchars=175&titles=Therion'
=> 'apihelp-query+extracts-example-1',
];
}
/**
* @inheritDoc
*/
public function getHelpUrls() {
return 'https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TextExtracts#API';
}
}

@ -0,0 +1,109 @@
<?php
namespace MediaWiki\Extension\TextExtracts;
use DOMElement;
use HtmlFormatter\HtmlFormatter;
use Wikimedia\Parsoid\Utils\DOMCompat;
/**
* Provides text-only or limited-HTML extracts of page HTML
*
* @license GPL-2.0-or-later
*/
class ExtractFormatter extends HtmlFormatter {
public const SECTION_MARKER_START = "<|startofsecion|>";
public const SECTION_MARKER_END = "<|endofsection|>";
/**
* @var bool
*/
private $plainText;
/**
* @param string $text Text to convert
* @param bool $plainText Whether extract should be plaintext
*/
public function __construct( $text, $plainText ) {
parent::__construct( HtmlFormatter::wrapHTML( $text ) );
$this->plainText = $plainText;
$this->setRemoveMedia( true );
if ( $plainText ) {
$this->flattenAllTags();
} else {
$this->flatten( [ 'a' ] );
}
}
/**
* Performs final transformations (such as newline replacement for plaintext
* option) and returns resulting HTML.
*
* @param DOMElement|string|null $element ID of element to get HTML from.
* Ignored
* @return string Processed HTML
*/
public function getText( $element = null ): string {
$this->filterContent();
$text = parent::getText();
if ( $this->plainText ) {
$text = html_entity_decode( $text );
// replace nbsp with space
$text = str_replace( "\u{00A0}", ' ', $text );
// for Windows
$text = str_replace( "\r", "\n", $text );
// normalise newlines
$text = preg_replace( "/\n{3,}/", "\n\n", $text );
}
return trim( $text );
}
/**
* @param string $html HTML string to process
* @return string Processed HTML
*/
public function onHtmlReady( string $html ): string {
if ( $this->plainText ) {
$html = preg_replace( '/\s*(<h([1-6])\b)/i',
"\n\n" . self::SECTION_MARKER_START . '$2' . self::SECTION_MARKER_END . '$1',
$html
);
}
return $html;
}
/**
* Removes content we've chosen to remove then removes class and style
* attributes from the remaining span elements.
*
* @return array Array of removed DOMElements
*/
public function filterContent(): array {
$doc = $this->getDoc();
// Headings in a DIV wrapper may get removed by $wgExtractsRemoveClasses,
// move it outside the header to rescue it (T363445)
// https://www.mediawiki.org/wiki/Heading_HTML_changes
$headings = DOMCompat::querySelectorAll( $doc->documentElement, 'h1, h2, h3, h4, h5, h6' );
foreach ( $headings as $heading ) {
// @phan-suppress-next-line PhanTypeMismatchArgumentSuperType
if ( DOMCompat::getClassList( $heading->parentNode )->contains( 'mw-heading' ) ) {
$heading->parentNode->parentNode->insertBefore( $heading, $heading->parentNode );
}
}
$removed = parent::filterContent();
$spans = $doc->getElementsByTagName( 'span' );
/** @var DOMElement $span */
foreach ( $spans as $span ) {
$span->removeAttribute( 'class' );
$span->removeAttribute( 'style' );
}
return $removed;
}
}

@ -0,0 +1,145 @@
<?php
namespace MediaWiki\Extension\TextExtracts;
use Generator;
use MediaWiki\Api\ApiMain;
use MediaWiki\Api\ApiResult;
use MediaWiki\Api\Hook\ApiOpenSearchSuggestHook;
use MediaWiki\Config\Config;
use MediaWiki\Config\ConfigFactory;
use MediaWiki\Request\FauxRequest;
use MediaWiki\Rest\Hook\SearchResultProvideDescriptionHook;
/**
* @license GPL-2.0-or-later
*/
class Hooks implements
ApiOpenSearchSuggestHook,
SearchResultProvideDescriptionHook
{
private Config $config;
public function __construct(
ConfigFactory $configFactory
) {
$this->config = $configFactory->makeConfig( 'textextracts' );
}
/**
* Trim an extract to a sensible length.
*
* Adapted from Extension:OpenSearchXml, which adapted it from
* Extension:ActiveAbstract.
*
* @param string $text
* @param int $length Target length; actual result will continue to the end of a sentence.
* @return string
*/
private static function trimExtract( $text, $length ) {
static $regex = null;
if ( $regex === null ) {
$endchars = [
// regular ASCII
'([^\d])\.\s', '\!\s', '\?\s',
// full-width ideographic full-stop
'。',
// double-width roman forms
'', '', '',
// half-width ideographic full stop
'。',
];
$endgroup = implode( '|', $endchars );
$end = "(?:$endgroup)";
$sentence = ".{{$length},}?$end+";
$regex = "/^($sentence)/u";
}
$matches = [];
if ( preg_match( $regex, $text, $matches ) ) {
return trim( $matches[1] );
} else {
// Just return the first line
return trim( explode( "\n", $text )[0] );
}
}
/**
* Retrieves extracts data for the given page IDs from the TextExtract API.
* The page IDs are chunked into the max limit of exlimit of the TextExtract API
*
* @param array $pageIds An array of page IDs to retrieve extracts for
* @return Generator Yields the result data from the API request
* $data = [
* 'pageId' => [
* 'ns' => int of the namespace
* 'title' => string of the title of the page
* 'extract' => string of the text extracts of the page
* ]
* ]
*/
private function getExtractsData( array $pageIds ) {
foreach ( array_chunk( $pageIds, 20 ) as $chunkedPageIds ) {
$api = new ApiMain( new FauxRequest(
[
'action' => 'query',
'prop' => 'extracts',
'explaintext' => true,
'exintro' => true,
'exlimit' => count( $chunkedPageIds ),
'pageids' => implode( '|', $chunkedPageIds ),
]
) );
$api->execute();
yield $api->getResult()->getResultData( [ 'query', 'pages' ] );
}
}
/**
* ApiOpenSearchSuggest hook handler
* @param array &$results Array of search results
*/
public function onApiOpenSearchSuggest( &$results ) {
if ( !$this->config->get( 'ExtractsExtendOpenSearchXml' ) || $results === [] ) {
return;
}
$pageIds = array_keys( $results );
foreach ( $this->getExtractsData( $pageIds ) as $data ) {
foreach ( $pageIds as $id ) {
$contentKey = $data[$id]['extract'][ApiResult::META_CONTENT] ?? '*';
if ( isset( $data[$id]['extract'][$contentKey] ) ) {
$results[$id]['extract'] = $data[$id]['extract'][$contentKey];
$results[$id]['extract trimmed'] = false;
}
}
}
}
/**
* Used to update Search Results with descriptions for Search Engine.
* @param array $pageIdentities Array (string=>SearchResultPageIdentity) where key is pageId
* @param array &$descriptions Output array (string=>string|null)
* where key is pageId and value is either a description for given page or null
*/
public function onSearchResultProvideDescription(
array $pageIdentities,
&$descriptions
): void {
if ( !$this->config->get( 'ExtractsExtendRestSearch' ) || $pageIdentities === [] ) {
return;
}
$pageIds = array_map( static function ( $identity ) {
return $identity->getId();
}, $pageIdentities );
foreach ( $this->getExtractsData( $pageIds ) as $data ) {
foreach ( $pageIds as $id ) {
$contentKey = $data[$id]['extract'][ApiResult::META_CONTENT] ?? '*';
if ( isset( $data[$id]['extract'][$contentKey] ) ) {
$descriptions[$id] = self::trimExtract( $data[$id]['extract'][$contentKey], 150 );
}
}
}
}
}

@ -0,0 +1,111 @@
<?php
namespace MediaWiki\Extension\TextExtracts;
use MediaWiki\MediaWikiServices;
/**
* This class needs to understand HTML as well as plain text. It tries to not break HTML tags, but
* might break pairs of tags, leaving unclosed tags behind. We can tidy the output to fix
* this.
*
* @license GPL-2.0-or-later
*/
class TextTruncator {
/**
* @var bool Whether to tidy the output
*/
private $useTidy;
/**
* @param bool $useTidy
*/
public function __construct( bool $useTidy ) {
$this->useTidy = $useTidy;
}
/**
* Returns no more than the given number of sentences
*
* @param string $text Source text to extract from
* @param int $requestedSentenceCount Maximum number of sentences to extract
* @return string
*/
public function getFirstSentences( $text, $requestedSentenceCount ) {
if ( $requestedSentenceCount <= 0 ) {
return '';
}
// Based on code from OpenSearchXml by Brion Vibber
$endchars = [
// regular ASCII
'\P{Lu}\.(?=[ \n]|$)',
'[!?](?=[ \n]|$)',
// full-width ideographic full-stop
'。',
// double-width roman forms
'',
'',
'',
// half-width ideographic full stop
'。',
];
$regexp = '/(?:' . implode( '|', $endchars ) . ')+/u';
$res = preg_match_all( $regexp, $text, $matches, PREG_OFFSET_CAPTURE );
if ( !$res ) {
// Just return the first line
$lines = explode( "\n", $text, 2 );
return trim( $lines[0] );
}
$index = min( $requestedSentenceCount, $res ) - 1;
[ $tail, $length ] = $matches[0][$index];
// PCRE returns raw offsets, so using substr() instead of mb_substr()
$text = substr( $text, 0, $length ) . $tail;
return $this->tidy( $text );
}
/**
* Returns no more than a requested number of characters, preserving words
*
* @param string $text Source text to extract from
* @param int $requestedLength Maximum number of characters to return
* @return string
*/
public function getFirstChars( $text, $requestedLength ) {
if ( $requestedLength <= 0 ) {
return '';
}
$length = mb_strlen( $text );
if ( $length <= $requestedLength ) {
return $text;
}
// This ungreedy pattern always matches, just might return an empty string
$pattern = '/^[\w\/]*>?/su';
preg_match( $pattern, mb_substr( $text, $requestedLength ), $m );
$truncatedText = mb_substr( $text, 0, $requestedLength ) . $m[0];
if ( $truncatedText === $text ) {
return $text;
}
return $this->tidy( $truncatedText );
}
/**
* @param string $text
* @return string
*/
private function tidy( $text ) {
if ( $this->useTidy ) {
$text = MediaWikiServices::getInstance()->getTidy()->tidy( $text );
}
return trim( $text );
}
}

@ -0,0 +1,274 @@
<?php
namespace MediaWiki\Extension\TextExtracts\Test;
use MediaWiki\Api\ApiBase;
use MediaWiki\Api\ApiMain;
use MediaWiki\Api\ApiQuery;
use MediaWiki\Config\ConfigFactory;
use MediaWiki\Config\HashConfig;
use MediaWiki\Context\IContextSource;
use MediaWiki\Extension\TextExtracts\ApiQueryExtracts;
use MediaWiki\Language\ILanguageConverter;
use MediaWiki\Language\Language;
use MediaWiki\Languages\LanguageConverterFactory;
use MediaWiki\Message\Message;
use MediaWiki\Title\Title;
use MediaWikiCoversValidator;
use Wikimedia\LightweightObjectStore\ExpirationAwareness;
use Wikimedia\ObjectCache\HashBagOStuff;
use Wikimedia\ObjectCache\WANObjectCache;
use Wikimedia\TestingAccessWrapper;
/**
* @covers MediaWiki\Extension\TextExtracts\ApiQueryExtracts
* @group TextExtracts
*
* @license GPL-2.0-or-later
*/
class ApiQueryExtractsTest extends \MediaWikiIntegrationTestCase {
use MediaWikiCoversValidator;
private function newInstance() {
$config = new HashConfig( [
'ParserCacheExpireTime' => ExpirationAwareness::TTL_INDEFINITE,
] );
$configFactory = $this->createMock( ConfigFactory::class );
$configFactory->method( 'makeConfig' )
->with( 'textextracts' )
->willReturn( $config );
$cache = new WANObjectCache( [ 'cache' => new HashBagOStuff() ] );
$context = $this->createMock( IContextSource::class );
$context->method( 'getConfig' )
->willReturn( $config );
$context->method( 'msg' )
->willReturnCallback( function ( $key, ...$params ) {
$msg = $this->createMock( Message::class );
$msg->method( 'text' )->willReturn( "($key)" );
return $msg;
} );
$main = $this->createMock( ApiMain::class );
$main->expects( $this->once() )
->method( 'getContext' )
->willReturn( $context );
$query = $this->createMock( ApiQuery::class );
$query->expects( $this->once() )
->method( 'getMain' )
->willReturn( $main );
$langConv = $this->createMock( ILanguageConverter::class );
$langConv->method( 'getPreferredVariant' )
->willReturn( 'en' );
$langConvFactory = $this->createMock( LanguageConverterFactory::class );
$langConvFactory->method( 'getLanguageConverter' )
->willReturn( $langConv );
return new ApiQueryExtracts(
$query,
'',
$configFactory,
$cache,
$langConvFactory,
$this->getServiceContainer()->getWikiPageFactory(),
$this->getServiceContainer()->getTitleFormatter()
);
}
public function testMemCacheHelpers() {
$title = $this->createMock( Title::class );
$title->method( 'getPageLanguage' )
->willReturn( $this->createMock( Language::class ) );
$page = $this->createMock( \WikiPage::class );
$page->method( 'getTitle' )
->willReturn( $title );
$page->method( 'getId' )
->willReturn( 123 );
$page->method( 'getTouched' )
->willReturn( '20010101000000' );
$text = 'Text to cache';
/** @var ApiQueryExtracts $instance */
$instance = TestingAccessWrapper::newFromObject( $this->newInstance() );
// Default param values for this API module
$instance->params = [ 'intro' => false, 'plaintext' => false ];
$this->assertFalse( $instance->getFromCache( $page, false ), 'is not cached yet' );
$instance->setCache( $page, $text );
$instance->cache->clearProcessCache();
$this->assertSame( $text, $instance->getFromCache( $page, false ) );
}
public function testSelfDocumentation() {
/** @var ApiQueryExtracts $instance */
$instance = TestingAccessWrapper::newFromObject( $this->newInstance() );
$this->assertIsString( $instance->getCacheMode( [] ) );
$this->assertNotEmpty( $instance->getExamplesMessages() );
$this->assertIsString( $instance->getHelpUrls() );
$params = $instance->getAllowedParams();
$this->assertIsArray( $params );
$this->assertSame( 1, $params['chars'][ApiBase::PARAM_MIN] );
$this->assertSame( 1200, $params['chars'][ApiBase::PARAM_MAX] );
$this->assertSame( 20, $params['limit'][ApiBase::PARAM_DFLT] );
$this->assertSame( 'limit', $params['limit'][ApiBase::PARAM_TYPE] );
$this->assertSame( 1, $params['limit'][ApiBase::PARAM_MIN] );
$this->assertSame( 20, $params['limit'][ApiBase::PARAM_MAX] );
$this->assertSame( 20, $params['limit'][ApiBase::PARAM_MAX2] );
}
/**
* @dataProvider provideFirstSectionsToExtract
*/
public function testGetFirstSection( $text, $isPlainText, $expected ) {
/** @var ApiQueryExtracts $instance */
$instance = TestingAccessWrapper::newFromObject( $this->newInstance() );
$this->assertSame( $expected, $instance->getFirstSection( $text, $isPlainText ) );
}
public static function provideFirstSectionsToExtract() {
return [
'Plain text match' => [
"First\nsection \1\2... \1\2...",
true,
"First\nsection ",
],
'Plain text without a match' => [
'Example\1\2...',
true,
'Example\1\2...',
],
'HTML match' => [
"First\nsection <h1>...<h2>...",
false,
"First\nsection ",
],
'HTML without a match' => [
'Example <h11>...',
false,
'Example <h11>...',
],
'__TOC__ before intro (HTML)' => [
'<h2 id="mw-toc-heading">Contents</h2>Intro<h2>Actual heading</h2>...',
false,
'<h2 id="mw-toc-heading">Contents</h2>Intro',
],
'__TOC__ before intro (plaintext)' => [
"\1\2_\2\1<h2 id=\"mw-toc-heading\">Contents</h2>Intro\1\2_\2\1<h2>Actual heading</h2>...",
true,
"\1\2_\2\1<h2 id=\"mw-toc-heading\">Contents</h2>Intro",
],
];
}
/**
* @dataProvider provideTextsToTruncate
*/
public function testTruncate( $text, array $params, $expected ) {
/** @var ApiQueryExtracts $instance */
$instance = TestingAccessWrapper::newFromObject( $this->newInstance() );
$instance->params = $params + [ 'chars' => null, 'sentences' => null, 'plaintext' => true ];
$this->assertSame( $expected, $instance->truncate( $text ) );
}
public static function provideTextsToTruncate() {
return [
[ '', [], '' ],
[ 'abc', [], 'abc' ],
[
'abc',
[ 'chars' => 1 ],
'abc'
],
[
'abc',
[ 'chars' => 1, 'plaintext' => false ],
'abc'
],
[
'abc',
[ 'sentences' => 1 ],
'abc'
],
[
'abc abc. xyz xyz.',
[ 'chars' => 1 ],
'abc(ellipsis)'
],
[
'abc abc. xyz xyz.',
[ 'sentences' => 1 ],
'abc abc.'
],
[
'abc abc. xyz xyz.',
[ 'chars' => 1000 ],
'abc abc. xyz xyz.'
],
[
'abc abc. xyz xyz.',
[ 'chars' => 1000, 'plaintext' => false ],
'abc abc. xyz xyz.'
],
[
'abc abc. xyz xyz.',
[ 'sentences' => 10 ],
'abc abc. xyz xyz.'
],
];
}
/**
* @dataProvider provideSectionsToFormat
*/
public function testDoSections( $text, $format, $expected ) {
/** @var ApiQueryExtracts $instance */
$instance = TestingAccessWrapper::newFromObject( $this->newInstance() );
$instance->params = [ 'sectionformat' => $format ];
$this->assertSame( $expected, $instance->doSections( $text ) );
}
public static function provideSectionsToFormat() {
$level = 3;
$marker = "\1\2$level\2\1";
return [
'Raw' => [
"$marker Headline\t\nNext line",
'raw',
"$marker Headline\t\nNext line",
],
'Wiki text' => [
"$marker Headline\t\nNext line",
'wiki',
"\n=== Headline ===\nNext line",
],
'Plain text' => [
"$marker Headline\t\nNext line",
'plain',
"\nHeadline\nNext line",
],
'Multiple matches' => [
"{$marker}First\n{$marker}Second",
'wiki',
"\n=== First ===\n\n=== Second ===",
],
];
}
}

@ -0,0 +1,108 @@
<?php
namespace MediaWiki\Extension\TextExtracts\Test;
use MediaWiki\Extension\TextExtracts\ExtractFormatter;
use MediaWikiIntegrationTestCase;
/**
* @covers MediaWiki\Extension\TextExtracts\ExtractFormatter
* @group TextExtracts
*
* @license GPL-2.0-or-later
*/
class ExtractFormatterTest extends MediaWikiIntegrationTestCase {
/**
* @dataProvider provideExtracts
*/
public function testExtracts( $expected, $text, $plainText ) {
$fmt = new ExtractFormatter( $text, $plainText );
// .metadata class will be added via $wgExtractsRemoveClasses on WMF
$fmt->remove( [ 'div', 'figure', '.metadata' ] );
$text = $fmt->getText();
$this->assertSame( $expected, $text );
}
public static function provideExtracts() {
// phpcs:ignore Generic.Files.LineLength
$dutch = '<b>Dutch</b> (<span class="unicode haudio" style="white-space:nowrap;"><span class="fn"><a href="/wiki/File:Nl-Nederlands.ogg" title="About this sound"><img alt="About this sound" src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/8a/Loudspeaker.svg/11px-Loudspeaker.svg.png" width="11" height="11" srcset="https://upload.wikimedia.org/wikipedia/commons/thumb/8/8a/Loudspeaker.svg/17px-Loudspeaker.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/8/8a/Loudspeaker.svg/22px-Loudspeaker.svg.png 2x" /></a>&#160;<a href="https://upload.wikimedia.org/wikipedia/commons/d/db/Nl-Nederlands.ogg" class="internal" title="Nl-Nederlands.ogg"><i>Nederlands</i></a></span>&#160;<small class="metadata audiolinkinfo" style="cursor:help;">(<a href="/w/index.php?title=Wikipedia:Media_help&amp;action=edit&amp;redlink=1" class="new" title="Wikipedia:Media help (page does not exist)"><span style="cursor:help;">help</span></a>·<a href="/wiki/File:Nl-Nederlands.ogg" title="File:Nl-Nederlands.ogg"><span style="cursor:help;">info</span></a>)</small></span>) is a <a href="/w/index.php?title=West_Germanic_languages&amp;action=edit&amp;redlink=1" class="new" title="West Germanic languages (page does not exist)">West Germanic language</a> and the native language of most of the population of the <a href="/w/index.php?title=Netherlands&amp;action=edit&amp;redlink=1" class="new" title="Netherlands (page does not exist)">Netherlands</a>';
$tocText = 'Lead<div id="toc" class="toc">TOC goes here</div>
<h1>Section</h1>
<p>Section text</p>';
// phpcs:ignore Generic.Files.LineLength
$figureText = '<b>Test 123</b>beforetext<figure><span><img alt="About this sound" src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/8a/Loudspeaker.svg/11px-Loudspeaker.svg.png" width="11" height="11" srcset="https://upload.wikimedia.org/wikipedia/commons/thumb/8/8a/Loudspeaker.svg/17px-Loudspeaker.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/8/8a/Loudspeaker.svg/22px-Loudspeaker.svg.png 2x" /></span><figcaption>Very loud speaker</figcaption></figure>aftertext';
return [
[
'Dutch ( Nederlands ) is a West Germanic language and the native language of ' .
'most of the population of the Netherlands',
$dutch,
true,
],
'HTML cleanup in HTML mode' => [
"\u{00A0}A &amp; <b>B</b>",
"&#x0A;&nbsp;<a>A</a> &amp; <b>&#x42;</b>\r\n",
false
],
'HTML cleanup in plain text mode' => [
'A & B',
"&#x0A;&nbsp;<a>A</a> &amp; <b>&#x42;</b>\r\n",
true
],
[
"<span><span lang=\"baz\">qux</span></span>",
'<span class="foo"><span lang="baz">qux</span></span>',
false,
],
[
"<span><span lang=\"baz\">qux</span></span>",
'<span style="foo: bar;"><span lang="baz">qux</span></span>',
false,
],
[
"<span><span lang=\"qux\">quux</span></span>",
'<span class="foo"><span style="bar: baz;" lang="qux">quux</span></span>',
false,
],
[
// New heading markup from T13555 (T363445)
"<p>hello</p><h2 id=\"heading\">heading</h2><p>bye</p>",
'<p>hello</p>' .
'<div class="mw-heading mw-heading2">' .
'<h2 id="heading">heading</h2>' .
'<span class="mw-editsection">xxx</span>' .
'</div>' .
'<p>bye</p>',
false,
],
[
// Verify that TOC is properly removed (HTML mode)
"Lead\n<h1>Section</h1>\n<p>Section text</p>",
$tocText,
false,
],
[
// Verify that TOC is properly removed (plain text mode)
"Lead\n\n\x01\x021\2\1Section\nSection text",
$tocText,
true,
],
[
// Verify that text in figures is removed (plain)
'Test 123beforetextaftertext',
$figureText,
true,
],
[
// Verify that text in figures is removed (html)
'<b>Test 123</b>beforetextaftertext',
$figureText,
false,
]
];
}
}

@ -0,0 +1,178 @@
<?php
namespace MediaWiki\Extension\TextExtracts\Test;
use MediaWiki\Extension\TextExtracts\TextTruncator;
/**
* @covers MediaWiki\Extension\TextExtracts\TextTruncator
* @group TextExtracts
*
* @license GPL-2.0-or-later
*/
class TextTruncatorTest extends \PHPUnit\Framework\TestCase {
/**
* @dataProvider provideGetFirstSentences
* @param string $text
* @param string $sentences
* @param string $expected
*/
public function testGetFirstSentences( $text, $sentences, $expected ) {
$truncator = new TextTruncator( false );
$this->assertSame( $expected, $truncator->getFirstSentences( $text, $sentences ) );
}
public static function provideGetFirstSentences() {
$longLine = str_repeat( 'word ', 1000000 );
return [
[
'Foo is a bar. Such a smart boy. But completely useless.',
2,
'Foo is a bar. Such a smart boy.',
],
[
'Foo is a bar. Such a smart boy. But completely useless.',
1,
'Foo is a bar.',
],
[
'Foo is a bar. Such a smart boy.',
2,
'Foo is a bar. Such a smart boy.',
],
[
'Foo is a bar.',
1,
'Foo is a bar.',
],
[
'Foo is a bar.',
2,
'Foo is a bar.',
],
[
'',
1,
'',
],
'0 sentences mean empty result' => [
'Foo is a bar. Such a smart boy.',
0,
'',
],
"Don't explode on negative input" => [
'Foo is a bar. Such a smart boy.',
-1,
'',
],
'More sentences requested than is available' => [
'Foo is a bar. Such a smart boy.',
3,
'Foo is a bar. Such a smart boy.',
],
// Exclamation points too!!!
[
'Foo is a bar! Such a smart boy! But completely useless!',
1,
'Foo is a bar!',
],
// A tricky one
[
"Acid phosphatase (EC 3.1.3.2) is a chemical you don't want to mess with. " .
"Polyvinyl acetate, however, is another story.",
1,
"Acid phosphatase (EC 3.1.3.2) is a chemical you don't want to mess with.",
],
// No clear sentences
[
"foo\nbar\nbaz",
2,
'foo',
],
// Bug T118621
[
'Foo was born in 1977. He enjoys listening to Siouxsie and the Banshees.',
1,
'Foo was born in 1977.',
],
// Bug T115795 - Test no cropping after initials
[
'P.J. Harvey is a singer. She is awesome!',
1,
'P.J. Harvey is a singer.',
],
// Bug T115817 - Non-breaking space is not a delimiter
[
html_entity_decode( 'Pigeons (lat.&nbsp;Columbidae) are birds. ' .
'They primarily feed on seeds.' ),
1,
html_entity_decode( 'Pigeons (lat.&nbsp;Columbidae) are birds.' ),
],
// Bug T145231 - various problems with regexes
[
$longLine,
3,
trim( $longLine ),
],
[
str_repeat( 'Sentence. ', 70000 ),
65536,
trim( str_repeat( 'Sentence. ', 65536 ) ),
],
'Preserve whitespace before end character' => [
'Aa . Bb',
1,
'Aa .',
],
];
}
/**
* @dataProvider provideGetFirstChars
* @param string $text
* @param string $chars
* @param string $expected
*/
public function testGetFirstChars( $text, $chars, $expected ) {
$truncator = new TextTruncator( false );
$this->assertSame( $expected, $truncator->getFirstChars( $text, $chars ) );
}
public static function provideGetFirstChars() {
$text = 'Lullzy lulz are lullzy!';
$html = 'foo<tag>bar</tag>';
$longText = str_repeat( 'тест ', 50000 );
$longTextExpected = trim( str_repeat( 'тест ', 13108 ) );
return [
[ $text, -8, '' ],
[ $text, 0, '' ],
[ $text, 100, $text ],
[ $text, 1, 'Lullzy' ],
[ $text, 6, 'Lullzy' ],
// [ $text, 7, 'Lullzy' ],
[ $text, 8, 'Lullzy lulz' ],
// HTML processing
[ $html, 1, 'foo' ],
// let HTML sanitizer clean it up later
[ $html, 4, 'foo<tag>' ],
[ $html, 12, 'foo<tag>bar</tag>' ],
[ $html, 13, 'foo<tag>bar</tag>' ],
[ $html, 16, 'foo<tag>bar</tag>' ],
[ $html, 17, 'foo<tag>bar</tag>' ],
// T143178 - previously, characters were extracted using regexps which failed when
// requesting 64K chars or more.
[ $longText, 65536, $longTextExpected ],
];
}
public function testTidyIntegration() {
$truncator = new TextTruncator( true );
$text = '<b>Aa. Bb.</b>';
$this->assertSame( '<p><b>Aa.</b></p>', $truncator->getFirstSentences( $text, 1 ) );
$this->assertSame( '<p><b>Aa</b></p>', $truncator->getFirstChars( $text, 4 ) );
}
}
Loading…
Cancel
Save