├── .gitignore ├── LICENSE ├── QtSnap7.pro ├── README.md ├── docs ├── CNAME ├── about │ ├── contributing.md │ ├── license.md │ └── release-notes.md ├── css │ └── extra.css ├── img │ ├── initial-layout.png │ ├── mkdocs.png │ ├── multipage.png │ ├── readthedocs.png │ ├── screenshot.png │ ├── search.png │ ├── site-name.png │ └── win-py-install.png ├── index.md └── user-guide │ ├── configuration.md │ ├── custom-themes.md │ ├── deploying-your-docs.md │ ├── plugins.md │ ├── styling-your-docs.md │ └── writing-your-docs.md ├── global.h ├── images ├── S71200-DB1 monitor.png ├── S71200-DB1.png ├── Thumbs.db └── Thumbs.db:encryptable ├── lib.pri ├── lib ├── snap7.dll └── snap7.lib ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h ├── mainwindow.ui ├── plc_siemens.cpp ├── plc_siemens.h ├── resources.qrc ├── settings.cpp ├── settings.h ├── snap7.cpp ├── snap7.h └── translation ├── translation_it.qm └── translation_it.ts /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | 3 | *.slo 4 | *.lo 5 | *.o 6 | *.a 7 | *.la 8 | *.lai 9 | *.so 10 | *.dll 11 | *.dylib 12 | 13 | # Qt-es 14 | 15 | /.qmake.cache 16 | /.qmake.stash 17 | *.pro.user 18 | *.pro.user.* 19 | *.qbs.user 20 | *.qbs.user.* 21 | *.moc 22 | moc_*.cpp 23 | moc_*.h 24 | qrc_*.cpp 25 | ui_*.h 26 | Makefile* 27 | *build-* 28 | 29 | # QtCreator 30 | 31 | *.autosave 32 | 33 | # QtCtreator Qml 34 | *.qmlproject.user 35 | *.qmlproject.user.* 36 | 37 | # QtCtreator CMake 38 | CMakeLists.txt.user* 39 | 40 | /gh_pages/site 41 | 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /QtSnap7.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2018-04-08T15:25:48 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = QtSnap7 12 | TEMPLATE = app 13 | 14 | # The following define makes your compiler emit warnings if you use 15 | # any feature of Qt which has been marked as deprecated (the exact warnings 16 | # depend on your compiler). Please consult the documentation of the 17 | # deprecated API in order to know how to port your code away from it. 18 | DEFINES += QT_DEPRECATED_WARNINGS 19 | 20 | # You can also make your code fail to compile if you use deprecated APIs. 21 | # In order to do so, uncomment the following line. 22 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 23 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 24 | 25 | SOURCES += \ 26 | main.cpp \ 27 | mainwindow.cpp \ 28 | snap7.cpp \ 29 | plc_siemens.cpp \ 30 | settings.cpp 31 | 32 | HEADERS += \ 33 | mainwindow.h \ 34 | snap7.h \ 35 | plc_siemens.h \ 36 | settings.h \ 37 | global.h 38 | 39 | FORMS += \ 40 | mainwindow.ui 41 | 42 | TRANSLATIONS = translation/translation_it.ts 43 | 44 | include("lib.pri") 45 | 46 | RESOURCES += \ 47 | resources.qrc 48 | 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QtSnap7 2 | [wiki]https://abedgnu.github.io/QtSnap7/ 3 | Qt5.9 snap7 S7-1200 cyclic reading 4 | 5 | #### Snap7 6 | 7 | http://snap7.sourceforge.net/ 8 | 9 | #### Qt5 10 | http://doc.qt.io/qt-5/qtexamplesandtutorials.html 11 | 12 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | www.mkdocs.org 2 | -------------------------------------------------------------------------------- /docs/about/contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing to MkDocs 2 | 3 | An introduction to contributing to the MkDocs project. 4 | 5 | The MkDocs project welcomes, and depends, on contributions from developers and 6 | users in the open source community. Contributions can be made in a number of 7 | ways, a few examples are: 8 | 9 | - Code patches via pull requests 10 | - Documentation improvements 11 | - Bug reports and patch reviews 12 | 13 | ## Code of Conduct 14 | 15 | Everyone interacting in the MkDocs project's codebases, issue trackers, chat 16 | rooms, and mailing lists is expected to follow the [PyPA Code of Conduct]. 17 | 18 | ## Reporting an Issue 19 | 20 | Please include as much detail as you can. Let us know your platform and MkDocs 21 | version. If the problem is visual (for example a theme or design issue) please 22 | add a screenshot and if you get an error please include the full error and 23 | traceback. 24 | 25 | ## Testing the Development Version 26 | 27 | If you want to just install and try out the latest development version of 28 | MkDocs you can do so with the following command. This can be useful if you 29 | want to provide feedback for a new feature or want to confirm if a bug you 30 | have encountered is fixed in the git master. It is **strongly** recommended 31 | that you do this within a [virtualenv]. 32 | 33 | ```bash 34 | pip install https://github.com/mkdocs/mkdocs/archive/master.tar.gz 35 | ``` 36 | 37 | ## Installing for Development 38 | 39 | First you'll need to fork and clone the repository. Once you have a local 40 | copy, run the following command. It is **strongly** recommended that you do 41 | this within a [virtualenv]. 42 | 43 | ```bash 44 | pip install --editable . 45 | ``` 46 | 47 | This will install MkDocs in development mode which binds the `mkdocs` command 48 | to the git repository. 49 | 50 | ## Running the tests 51 | 52 | To run the tests, it is recommended that you use [Tox]. This just needs 53 | to be pip installed and then the test suite can be ran for MkDocs but running 54 | the command `tox` in the root of your MkDocs repository. 55 | 56 | It will attempt to run the tests against all of the Python versions we 57 | support. So don't be concerned if you are missing some and they fail. The rest 58 | will be verified by [Travis] when you submit a pull request. 59 | 60 | ## Submitting Pull Requests 61 | 62 | Once you are happy with your changes or you are ready for some feedback, push 63 | it to your fork and send a pull request. For a change to be accepted it will 64 | most likely need to have tests and documentation if it is a new feature. 65 | 66 | [virtualenv]: https://virtualenv.pypa.io/en/latest/userguide.html 67 | [tox]: https://tox.readthedocs.io/en/latest/ 68 | [travis]: https://travis-ci.org/repositories 69 | [PyPA Code of Conduct]: https://www.pypa.io/en/latest/code-of-conduct/ 70 | -------------------------------------------------------------------------------- /docs/about/license.md: -------------------------------------------------------------------------------- 1 | # License 2 | 3 | The legal stuff. 4 | 5 | --- 6 | 7 | ## Included projects 8 | 9 | Themes used under license from the ReadTheDocs projects. 10 | 11 | * ReadTheDocs theme - [View license](https://github.com/snide/sphinx_rtd_theme/blob/master/LICENSE). 12 | 13 | Many thanks to the authors and contributors of those wonderful projects. 14 | 15 | ## MkDocs License (BSD) 16 | 17 | Copyright © 2014, Tom Christie. All rights reserved. 18 | 19 | Redistribution and use in source and binary forms, with or without modification, 20 | are permitted provided that the following conditions are met: 21 | 22 | Redistributions of source code must retain the above copyright notice, this list 23 | of conditions and the following disclaimer. Redistributions in binary form must 24 | reproduce the above copyright notice, this list of conditions and the following 25 | disclaimer in the documentation and/or other materials provided with the 26 | distribution. 27 | 28 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 29 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 30 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 31 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 32 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 33 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 34 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 35 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 37 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | -------------------------------------------------------------------------------- /docs/css/extra.css: -------------------------------------------------------------------------------- 1 | div.col-md-9 h1:first-of-type { 2 | text-align: center; 3 | font-size: 60px; 4 | font-weight: 300; 5 | } 6 | 7 | div.col-md-9>p:first-of-type { 8 | text-align: center; 9 | } 10 | 11 | div.col-md-9 p.admonition-title:first-of-type { 12 | text-align: left; 13 | } 14 | 15 | div.col-md-9 h1:first-of-type .headerlink { 16 | display: none; 17 | } 18 | 19 | code.no-highlight { 20 | color: black; 21 | } 22 | 23 | /* Definition List styles */ 24 | 25 | dd { 26 | padding-left: 20px; 27 | } 28 | -------------------------------------------------------------------------------- /docs/img/initial-layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abedGNU/QtSnap7/fa9cedc137408377cfe77457e46d1b332a7612ea/docs/img/initial-layout.png -------------------------------------------------------------------------------- /docs/img/mkdocs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abedGNU/QtSnap7/fa9cedc137408377cfe77457e46d1b332a7612ea/docs/img/mkdocs.png -------------------------------------------------------------------------------- /docs/img/multipage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abedGNU/QtSnap7/fa9cedc137408377cfe77457e46d1b332a7612ea/docs/img/multipage.png -------------------------------------------------------------------------------- /docs/img/readthedocs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abedGNU/QtSnap7/fa9cedc137408377cfe77457e46d1b332a7612ea/docs/img/readthedocs.png -------------------------------------------------------------------------------- /docs/img/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abedGNU/QtSnap7/fa9cedc137408377cfe77457e46d1b332a7612ea/docs/img/screenshot.png -------------------------------------------------------------------------------- /docs/img/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abedGNU/QtSnap7/fa9cedc137408377cfe77457e46d1b332a7612ea/docs/img/search.png -------------------------------------------------------------------------------- /docs/img/site-name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abedGNU/QtSnap7/fa9cedc137408377cfe77457e46d1b332a7612ea/docs/img/site-name.png -------------------------------------------------------------------------------- /docs/img/win-py-install.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abedGNU/QtSnap7/fa9cedc137408377cfe77457e46d1b332a7612ea/docs/img/win-py-install.png -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # MkDocs 2 | 3 | Project documentation with Markdown. 4 | 5 | --- 6 | 7 | ## Overview 8 | 9 | MkDocs is a **fast**, **simple** and **downright gorgeous** static site 10 | generator that's geared towards building project documentation. Documentation 11 | source files are written in Markdown, and configured with a single YAML 12 | configuration file. 13 | 14 | ### Host anywhere 15 | 16 | MkDocs builds completely static HTML sites that you can host on GitHub pages, 17 | Amazon S3, or [anywhere][deploy] else you choose. 18 | 19 | ### Great themes available 20 | 21 | There's a stack of good looking themes available for MkDocs. Choose between 22 | the built in themes: [mkdocs] and [readthedocs], select one of the 3rd 23 | party themes in the [MkDocs wiki], or [build your own]. 24 | 25 | ### Preview your site as you work 26 | 27 | The built-in dev-server allows you to preview your documentation as you're 28 | writing it. It will even auto-reload and refresh your browser whenever you save 29 | your changes. 30 | 31 | ### Easy to customize 32 | 33 | Get your project documentation looking just the way you want it by customizing 34 | the theme. 35 | 36 | --- 37 | 38 | ## Installation 39 | 40 | ### Install with a Package Manager 41 | 42 | If you have and use a package manager (such as [apt-get], [dnf], [homebrew], 43 | [yum], [chocolatey], etc.) to install packages on your system, then you may 44 | want to search for a "MkDocs" package and, if a recent version is available, 45 | install it with your package manager (check your system's documentation for 46 | details). That's it, you're done! Skip down to [Getting Started](#getting-started). 47 | 48 | If your package manager does not have a recent "MkDocs" package, you can still 49 | use your package manager to install "Python" and "pip". Then you can use pip to 50 | [install MkDocs](#installing-mkdocs). 51 | 52 | [apt-get]: https://help.ubuntu.com/community/AptGet/Howto 53 | [homebrew]: https://brew.sh/ 54 | [dnf]: http://dnf.readthedocs.io/en/latest/index.html 55 | [yum]: http://yum.baseurl.org/ 56 | [chocolatey]: https://chocolatey.org/ 57 | 58 | ### Manual Installation 59 | 60 | In order to manually install MkDocs you'll need [Python] installed on your 61 | system, as well as the Python package manager, [pip]. You can check if you have 62 | these already installed from the command line: 63 | 64 | ```bash 65 | $ python --version 66 | Python 2.7.2 67 | $ pip --version 68 | pip 1.5.2 69 | ``` 70 | 71 | MkDocs supports Python versions 2.7, 3.4, 3.5, 3.6, 3.7 and pypy. 72 | 73 | #### Installing Python 74 | 75 | Install [Python] by downloading an installer appropriate for your system from 76 | [python.org] and running it. 77 | 78 | !!! Note 79 | 80 | If you are installing Python on Windows, be sure to check the box to have 81 | Python added to your PATH if the installer offers such an option (it's 82 | normally off by default). 83 | 84 | ![Add Python to PATH](img/win-py-install.png) 85 | 86 | [python.org]: https://www.python.org/downloads/ 87 | 88 | #### Installing pip 89 | 90 | If you're using a recent version of Python, the Python package manager, [pip], 91 | is most likely installed by default. However, you may need to upgrade pip to the 92 | lasted version: 93 | 94 | ```bash 95 | pip install --upgrade pip 96 | ``` 97 | 98 | If you need to install [pip] for the first time, download [get-pip.py]. 99 | Then run the following command to install it: 100 | 101 | ```bash 102 | python get-pip.py 103 | ``` 104 | 105 | #### Installing MkDocs 106 | 107 | Install the `mkdocs` package using pip: 108 | 109 | ```bash 110 | pip install mkdocs 111 | ``` 112 | 113 | You should now have the `mkdocs` command installed on your system. Run `mkdocs 114 | --version` to check that everything worked okay. 115 | 116 | ```bash 117 | $ mkdocs --version 118 | mkdocs, version 0.15.3 119 | ``` 120 | 121 | !!! Note 122 | If you would like manpages installed for MkDocs, the [click-man] tool can 123 | generate and install them for you. Simply run the following two commands: 124 | 125 | pip install click-man 126 | click-man --target path/to/man/pages mkdocs 127 | 128 | See the [click-man documentation] for an explaination of why manpages are 129 | not automaticaly generated and installed by pip. 130 | 131 | [click-man]: https://github.com/click-contrib/click-man 132 | [click-man documentation]: https://github.com/click-contrib/click-man#automatic-man-page-installation-with-setuptools-and-pip 133 | 134 | !!! Note 135 | If you are using Windows, some of the above commands may not work 136 | out-of-the-box. 137 | 138 | A quick solution may be to preface every Python command with `python -m` 139 | like this: 140 | 141 | python -m pip install mkdocs 142 | python -m mkdocs 143 | 144 | For a more permanent solution, you may need to edit your `PATH` environment 145 | variable to include the `Scripts` directory of your Python installation. 146 | Recent versions of Python include a script to do this for you. Navigate to 147 | your Python installation directory (for example `C:\Python34\`), open the 148 | `Tools`, then `Scripts` folder, and run the `win_add2path.py` file by double 149 | clicking on it. Alternatively, you can [download][a2p] the script and run it 150 | (`python win_add2path.py`). 151 | 152 | [a2p]: https://svn.python.org/projects/python/trunk/Tools/scripts/win_add2path.py 153 | 154 | --- 155 | 156 | ## Getting Started 157 | 158 | Getting started is super easy. 159 | 160 | ```bash 161 | mkdocs new my-project 162 | cd my-project 163 | ``` 164 | 165 | Take a moment to review the initial project that has been created for you. 166 | 167 | ![The initial MkDocs layout](img/initial-layout.png) 168 | 169 | There's a single configuration file named `mkdocs.yml`, and a folder named 170 | `docs` that will contain your documentation source files. Right now the `docs` 171 | folder just contains a single documentation page, named `index.md`. 172 | 173 | MkDocs comes with a built-in dev-server that lets you preview your documentation 174 | as you work on it. Make sure you're in the same directory as the `mkdocs.yml` 175 | configuration file, and then start the server by running the `mkdocs serve` 176 | command: 177 | 178 | ```bash 179 | $ mkdocs serve 180 | INFO - Building documentation... 181 | INFO - Cleaning site directory 182 | [I 160402 15:50:43 server:271] Serving on http://127.0.0.1:8000 183 | [I 160402 15:50:43 handlers:58] Start watching changes 184 | [I 160402 15:50:43 handlers:60] Start detecting changes 185 | ``` 186 | 187 | Open up `http://127.0.0.1:8000/` in your browser, and you'll see the default 188 | home page being displayed: 189 | 190 | ![The MkDocs live server](img/screenshot.png) 191 | 192 | The dev-server also supports auto-reloading, and will rebuild your documentation 193 | whenever anything in the configuration file, documentation directory, or theme 194 | directory changes. 195 | 196 | Open the `docs/index.md` document in your text editor of choice, change the 197 | initial heading to `MkLorum`, and save your changes. Your browser will 198 | auto-reload and you should see your updated documentation immediately. 199 | 200 | Now try editing the configuration file: `mkdocs.yml`. Change the 201 | [`site_name`][site_name] setting to `MkLorum` and save the file. 202 | 203 | ```yaml 204 | site_name: MkLorum 205 | ``` 206 | 207 | Your browser should immediately reload, and you'll see your new site name take 208 | effect. 209 | 210 | ![The site_name setting](img/site-name.png) 211 | 212 | ## Adding pages 213 | 214 | Now add a second page to your documentation: 215 | 216 | ```bash 217 | curl 'https://jaspervdj.be/lorem-markdownum/markdown.txt' > docs/about.md 218 | ``` 219 | 220 | As our documentation site will include some navigation headers, you may want to 221 | edit the configuration file and add some information about the order, title, and 222 | nesting of each page in the navigation header by adding a [`pages`][pages] 223 | setting: 224 | 225 | ```yaml 226 | site_name: MkLorum 227 | pages: 228 | - Home: index.md 229 | - About: about.md 230 | ``` 231 | 232 | Save your changes and you'll now see a navigation bar with `Home` and `About` 233 | items on the left as well as `Search`, `Previous`, and `Next` items on the 234 | right. 235 | 236 | ![Screenshot](img/multipage.png) 237 | 238 | Try the menu items and navigate back and forth between pages. Then click on 239 | `Search`. A search dialog will appear, allowing you to search for any text on 240 | any page. Notice that the search results include every occurrence of the search 241 | term on the site and links directly to the section of the page in which the 242 | search term appears. You get of all that with no effort or configuration on your 243 | part! 244 | 245 | ![Screenshot](img/search.png) 246 | 247 | ## Theming our documentation 248 | 249 | Now change the configuration file to alter how the documentation is displayed by 250 | changing the theme. Edit the `mkdocs.yml` file and add a [`theme`][theme] setting: 251 | 252 | ```yaml 253 | site_name: MkLorum 254 | pages: 255 | - Home: index.md 256 | - About: about.md 257 | theme: readthedocs 258 | ``` 259 | 260 | Save your changes, and you'll see the ReadTheDocs theme being used. 261 | 262 | ![Screenshot](img/readthedocs.png) 263 | 264 | ## Changing the Favicon Icon 265 | 266 | By default, MkDocs uses the [MkDocs favicon] icon. To use a different icon, create 267 | an `img` subdirectory in your `docs_dir` and copy your custom `favicon.ico` file 268 | to that directory. MkDocs will automatically detect and use that file as your 269 | favicon icon. 270 | 271 | [MkDocs favicon]: /img/favicon.ico 272 | 273 | ## Building the site 274 | 275 | That's looking good. You're ready to deploy the first pass of your `MkLorum` 276 | documentation. First build the documentation: 277 | 278 | ```bash 279 | mkdocs build 280 | ``` 281 | 282 | This will create a new directory, named `site`. Take a look inside the 283 | directory: 284 | 285 | ```bash 286 | $ ls site 287 | about fonts index.html license search.html 288 | css img js mkdocs sitemap.xml 289 | ``` 290 | 291 | Notice that your source documentation has been output as two HTML files named 292 | `index.html` and `about/index.html`. You also have various other media that's 293 | been copied into the `site` directory as part of the documentation theme. You 294 | even have a `sitemap.xml` file and `mkdocs/search_index.json`. 295 | 296 | If you're using source code control such as `git` you probably don't want to 297 | check your documentation builds into the repository. Add a line containing 298 | `site/` to your `.gitignore` file. 299 | 300 | ```bash 301 | echo "site/" >> .gitignore 302 | ``` 303 | 304 | If you're using another source code control tool you'll want to check its 305 | documentation on how to ignore specific directories. 306 | 307 | After some time, files may be removed from the documentation but they will still 308 | reside in the `site` directory. To remove those stale files, just run `mkdocs` 309 | with the `--clean` switch. 310 | 311 | ```bash 312 | mkdocs build --clean 313 | ``` 314 | 315 | ## Other Commands and Options 316 | 317 | There are various other commands and options available. For a complete list of 318 | commands, use the `--help` flag: 319 | 320 | ```bash 321 | mkdocs --help 322 | ``` 323 | 324 | To view a list of options available on a given command, use the `--help` flag 325 | with that command. For example, to get a list of all options available for the 326 | `build` command run the following: 327 | 328 | ```bash 329 | mkdocs build --help 330 | ``` 331 | 332 | ## Deploying 333 | 334 | The documentation site that you just built only uses static files so you'll be 335 | able to host it from pretty much anywhere. [GitHub project pages] and [Amazon 336 | S3] may be good hosting options, depending upon your needs. Upload the contents 337 | of the entire `site` directory to wherever you're hosting your website from and 338 | you're done. For specific instructions on a number of common hosts, see the 339 | [Deploying your Docs][deploy] page. 340 | 341 | ## Getting help 342 | 343 | To get help with MkDocs, please use the [discussion group], [GitHub issues] or 344 | the MkDocs IRC channel `#mkdocs` on freenode. 345 | 346 | [deploy]: user-guide/deploying-your-docs/ 347 | [mkdocs]: user-guide/styling-your-docs/#mkdocs 348 | [readthedocs]: user-guide/styling-your-docs/#readthedocs 349 | [MkDocs wiki]: https://github.com/mkdocs/mkdocs/wiki/MkDocs-Themes 350 | [build your own]: user-guide/custom-themes/ 351 | [Amazon S3]: https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html 352 | [get-pip.py]: https://bootstrap.pypa.io/get-pip.py 353 | [pages]: user-guide/configuration/#pages 354 | [discussion group]: https://groups.google.com/forum/#!forum/mkdocs 355 | [GitHub issues]: https://github.com/mkdocs/mkdocs/issues 356 | [GitHub project pages]: https://help.github.com/articles/creating-project-pages-manually/ 357 | [pip]: http://pip.readthedocs.io/en/stable/installing/ 358 | [Python]: https://www.python.org/ 359 | [site_name]: user-guide/configuration/#site_name 360 | [theme]: user-guide/configuration/#theme 361 | -------------------------------------------------------------------------------- /docs/user-guide/configuration.md: -------------------------------------------------------------------------------- 1 | # Configuration 2 | 3 | Guide to all available configuration settings. 4 | 5 | --- 6 | 7 | ## Introduction 8 | 9 | Project settings are always configured by using a YAML configuration file in the 10 | project directory named `mkdocs.yml`. 11 | 12 | As a minimum this configuration file must contain the `site_name` setting. All 13 | other settings are optional. 14 | 15 | ## Project information 16 | 17 | ### site_name 18 | 19 | This is a **required setting**, and should be a string that is used as the main 20 | title for the project documentation. For example: 21 | 22 | ```yaml 23 | site_name: Marshmallow Generator 24 | ``` 25 | 26 | When rendering the theme this setting will be passed as the `site_name` context 27 | variable. 28 | 29 | ### site_url 30 | 31 | Set the canonical URL of the site. This will add a link tag with the canonical 32 | URL to the generated HTML header. 33 | 34 | **default**: `null` 35 | 36 | ### repo_url 37 | 38 | When set, provides a link to your repository (GitHub, Bitbucket, GitLab, ...) 39 | on each page. 40 | 41 | ```yaml 42 | repo_url: https://github.com/example/repository/ 43 | ``` 44 | 45 | **default**: `null` 46 | 47 | ### repo_name 48 | 49 | When set, provides the name for the link to your repository on each page. 50 | 51 | **default**: `'GitHub'`, `'Bitbucket'` or `'GitLab'` if the `repo_url` matches 52 | those domains, otherwise the hostname from the `repo_url`. 53 | 54 | ### edit_uri 55 | 56 | Path from the base `repo_url` to the docs directory when directly viewing a 57 | page, accounting for specifics of the repository host (e.g. GitHub, Bitbucket, 58 | etc), the branch, and the docs directory itself. MkDocs concatenates `repo_url` 59 | and `edit_uri`, and appends the input path of the page. 60 | 61 | When set, and if your theme supports it, provides a link directly to the page in 62 | your source repository. This makes it easier to find and edit the source for the 63 | page. If `repo_url` is not set, this option is ignored. On some themes, setting 64 | this option may cause an edit link to be used in place of a repository link. 65 | Other themes may show both links. 66 | 67 | The `edit_uri` supports query ('?') and fragment ('#') characters. For 68 | repository hosts that use a query or a fragment to access the files, the 69 | `edit_uri` might be set as follows. (Note the `?` and `#` in the URI...) 70 | 71 | ```yaml 72 | # Query string example 73 | edit_uri: '?query=root/path/docs/' 74 | ``` 75 | 76 | ```yaml 77 | # Hash fragment example 78 | edit_uri: '#root/path/docs/' 79 | ``` 80 | 81 | For other repository hosts, simply specify the relative path to the docs 82 | directory. 83 | 84 | ```yaml 85 | # Query string example 86 | edit_uri: root/path/docs/ 87 | ``` 88 | 89 | !!! note 90 | On a few known hosts (specifically GitHub, Bitbucket and GitLab), the 91 | `edit_uri` is derived from the 'repo_url' and does not need to be set 92 | manually. Simply defining a `repo_url` will automatically populate the 93 | `edit_uri` configs setting. 94 | 95 | For example, for a GitHub- or GitLab-hosted repository, the `edit_uri` 96 | would be automatically set as `edit/master/docs/` (Note the `edit` path 97 | and `master` branch). 98 | 99 | For a Bitbucket-hosted repository, the equivalent `edit_uri` would be 100 | automatically set as `src/default/docs/` (note the `src` path and `default` 101 | branch). 102 | 103 | To use a different URI than the default (for example a different branch), 104 | simply set the `edit_uri` to your desired string. If you do not want any 105 | "edit URL link" displayed on your pages, then set `edit_uri` to an empty 106 | string to disable the automatic setting. 107 | 108 | !!! warning 109 | On GitHub and GitLab, the default "edit" path (`edit/master/docs/`) opens 110 | the page in the online editor. This functionality requires that the user 111 | have and be logged in to a GitHub/GitLab account. Otherwise, the user will 112 | be redirected to a login/signup page. Alternatively, use the "blob" path 113 | (`blob/master/docs/`) to open a read-only view, which supports anonymous 114 | access. 115 | 116 | **default**: `edit/master/docs/` for GitHub and GitLab repos or 117 | `src/default/docs/` for a Bitbucket repo, if `repo_url` matches those domains, 118 | otherwise `null` 119 | 120 | ### site_description 121 | 122 | Set the site description. This will add a meta tag to the generated HTML header. 123 | 124 | **default**: `null` 125 | 126 | ### site_author 127 | 128 | Set the name of the author. This will add a meta tag to the generated HTML 129 | header. 130 | 131 | **default**: `null` 132 | 133 | ### copyright 134 | 135 | Set the copyright information to be included in the documentation by the theme. 136 | 137 | **default**: `null` 138 | 139 | ### google_analytics 140 | 141 | Set the Google analytics tracking configuration. 142 | 143 | ```yaml 144 | google_analytics: ['UA-36723568-3', 'mkdocs.org'] 145 | ``` 146 | 147 | **default**: `null` 148 | 149 | ### remote_branch 150 | 151 | Set the remote branch to commit to when using `gh-deploy` to deploy to Github 152 | Pages. This option can be overridden by a command line option in `gh-deploy`. 153 | 154 | **default**: `gh-pages` 155 | 156 | ### remote_name 157 | 158 | Set the remote name to push to when using `gh-deploy` to deploy to Github Pages. 159 | This option can be overridden by a command line option in `gh-deploy`. 160 | 161 | **default**: `origin` 162 | 163 | ## Documentation layout 164 | 165 | ### nav 166 | 167 | This setting is used to determine the format and layout of the global navigation 168 | for the site. For example, the following would create "Introduction", "User 169 | Guide" and "About" navigation items. 170 | 171 | ```yaml 172 | nav: 173 | - 'Introduction': 'index.md' 174 | - 'User Guide': 'user-guide.md' 175 | - 'About': 'about.md' 176 | ``` 177 | 178 | All paths must be relative to the `mkdocs.yml` configuration file. See the 179 | section on [configuring pages and navigation] for a more detailed breakdown, 180 | including how to create sub-sections. 181 | 182 | Navigation items may also include links to external sites. While titles are 183 | optional for internal links, they are required for external links. An external 184 | link may be a full URL or a relative URL. Any path which is not found in the 185 | files is assumed to be an external link. 186 | 187 | ```yaml 188 | nav: 189 | - Home: index.md 190 | - User Guide: user-guide.md 191 | - Bug Tracker: https://example.com/ 192 | ``` 193 | 194 | In the above example, the first two items point to local files while the third 195 | points to an external site. 196 | 197 | However, sometimes the MkDocs site is hosted in a subdirectory of a project's 198 | site and you may want to link to other parts of the same site without including 199 | the full domain. In that case, you may use and appropriate relative URL. 200 | 201 | ```yaml 202 | site_url: https://example.com/foo/ 203 | 204 | nav: 205 | - Home: ../ 206 | - User Guide: user-guide.md 207 | - Bug Tracker: /bugs/ 208 | ``` 209 | 210 | In the above example, two different styles of external links are used. First 211 | note that the `site_url` indicates that the MkDocs site is hosted in the `/foo/` 212 | subdirectory of the domain. Therefore, the `Home` navigation item is a relative 213 | link which steps up one level to the server root and effectively points to 214 | `https://example.com/`. The `Bug Tracker` item uses an absolute path from the 215 | server root and effectively points to `https://example.com/bugs/`. Of course, the 216 | `User Guide` points to a local MkDocs page. 217 | 218 | **default**: By default `nav` will contain an alphanumerically sorted, nested 219 | list of all the Markdown files found within the `docs_dir` and its 220 | sub-directories. If none are found it will be `[]` (an empty list). 221 | 222 | ## Build directories 223 | 224 | ### theme 225 | 226 | Sets the theme and theme specific configuration of your documentation site. 227 | May be either a string or a set of key/value pairs. 228 | 229 | If a string, it must be the string name of a known installed theme. For a list 230 | of available themes visit [styling your docs]. 231 | 232 | An example set of key/value pairs might look something like this: 233 | 234 | ```yaml 235 | theme: 236 | name: mkdocs 237 | custom_dir: my_theme_customizations/ 238 | static_templates: 239 | - sitemap.html 240 | include_sidebar: false 241 | ``` 242 | 243 | If a set of key/value pairs, the following nested keys can be defined: 244 | 245 | !!! block "" 246 | 247 | #### name: 248 | 249 | The string name of a known installed theme. For a list of available themes 250 | visit [styling your docs]. 251 | 252 | #### custom_dir: 253 | 254 | A directory containing a custom theme. This can either be a relative 255 | directory, in which case it is resolved relative to the directory containing 256 | your configuration file, or it can be an absolute directory path from the 257 | root of your local file system. 258 | 259 | See [styling your docs][theme_dir] for details if you would like to tweak an 260 | existing theme. 261 | 262 | See [custom themes] if you would like to build your own theme from the 263 | ground up. 264 | 265 | #### static_templates: 266 | 267 | A list of templates to render as static pages. The templates must be located 268 | in either the theme's template directory or in the `custom_dir` defined in 269 | the theme configuration. 270 | 271 | #### (theme specific keywords) 272 | 273 | Any additional keywords supported by the theme can also be defined. See the 274 | documentation for the theme you are using for details. 275 | 276 | **default**: `'mkdocs'` 277 | 278 | ### docs_dir 279 | 280 | The directory containing the documentation source markdown files. This can 281 | either be a relative directory, in which case it is resolved relative to the 282 | directory containing your configuration file, or it can be an absolute directory 283 | path from the root of your local file system. 284 | 285 | **default**: `'docs'` 286 | 287 | ### site_dir 288 | 289 | The directory where the output HTML and other files are created. This can either 290 | be a relative directory, in which case it is resolved relative to the directory 291 | containing your configuration file, or it can be an absolute directory path from 292 | the root of your local file system. 293 | 294 | **default**: `'site'` 295 | 296 | !!! note "Note:" 297 | If you are using source code control you will normally want to ensure that 298 | your *build output* files are not committed into the repository, and only 299 | keep the *source* files under version control. For example, if using `git` 300 | you might add the following line to your `.gitignore` file: 301 | 302 | site/ 303 | 304 | If you're using another source code control tool, you'll want to check its 305 | documentation on how to ignore specific directories. 306 | 307 | ### extra_css 308 | 309 | Set a list of CSS files in your `docs_dir` to be included by the theme. For 310 | example, the following example will include the extra.css file within the 311 | css subdirectory in your [docs_dir](#docs_dir). 312 | 313 | ```yaml 314 | extra_css: 315 | - css/extra.css 316 | - css/second_extra.css 317 | ``` 318 | 319 | **default**: `[]` (an empty list). 320 | 321 | ### extra_javascript 322 | 323 | Set a list of JavaScript files in your `docs_dir` to be included by the theme. 324 | See the example in [extra_css] for usage. 325 | 326 | **default**: `[]` (an empty list). 327 | 328 | ### extra_templates 329 | 330 | Set a list of templates in your `docs_dir` to be built by MkDocs. To see more 331 | about writing templates for MkDocs read the documentation about [custom themes] 332 | and specifically the section about the [variables that are available] to 333 | templates. See the example in [extra_css] for usage. 334 | 335 | **default**: `[]` (an empty list). 336 | 337 | ### extra 338 | 339 | A set of key value pairs, where the values can be any valid YAML construct, that 340 | will be passed to the template. This allows for great flexibility when creating 341 | custom themes. 342 | 343 | For example, if you are using a theme that supports displaying the project 344 | version, you can pass it to the theme like this: 345 | 346 | ```yaml 347 | extra: 348 | version: 1.0 349 | ``` 350 | 351 | **default**: By default `extra` will be an empty key value mapping. 352 | 353 | ## Preview controls 354 | 355 | ### use_directory_urls 356 | 357 | This setting controls the style used for linking to pages within the 358 | documentation. 359 | 360 | The following table demonstrates how the URLs used on the site differ when 361 | setting `use_directory_urls` to `true` or `false`. 362 | 363 | Source file | use_directory_urls: true | use_directory_urls: false 364 | ---------------- | ------------------------- | ------------------------- 365 | index.md | / | /index.html 366 | api-guide.md | /api-guide/ | /api-guide.html 367 | about/license.md | /about/license/ | /about/license.html 368 | 369 | The default style of `use_directory_urls: true` creates more user friendly URLs, 370 | and is usually what you'll want to use. 371 | 372 | The alternate style can occasionally be useful if you want your documentation to 373 | remain properly linked when opening pages directly from the file system, because 374 | it creates links that point directly to the target *file* rather than the target 375 | *directory*. 376 | 377 | **default**: `true` 378 | 379 | ### strict 380 | 381 | Determines how warnings are handled. Set to `true` to halt processing when a 382 | warning is raised. Set to `false` to print a warning and continue processing. 383 | 384 | **default**: `false` 385 | 386 | ### dev_addr 387 | 388 | Determines the address used when running `mkdocs serve`. Must be of the format 389 | `IP:PORT`. 390 | 391 | Allows a custom default to be set without the need to pass it through the 392 | `--dev_addr` option every time the `mkdocs serve` command is called. 393 | 394 | **default**: `'127.0.0.1:8000'` 395 | 396 | ## Formatting options 397 | 398 | ### markdown_extensions 399 | 400 | MkDocs uses the [Python Markdown][pymkd] library to translate Markdown files 401 | into HTML. Python Markdown supports a variety of [extensions][pymdk-extensions] 402 | that customize how pages are formatted. This setting lets you enable a list of 403 | extensions beyond the ones that MkDocs uses by default (`meta`, `toc`, `tables`, 404 | and `fenced_code`). 405 | 406 | For example, to enable the [SmartyPants typography extension][smarty], use: 407 | 408 | ```yaml 409 | markdown_extensions: 410 | - smarty 411 | ``` 412 | 413 | Some extensions provide configuration options of their own. If you would like to 414 | set any configuration options, then you can nest a key/value mapping 415 | (`option_name: option value`) of any options that a given extension supports. 416 | See the documentation for the extension you are using to determine what options 417 | they support. 418 | 419 | For example, to enable permalinks in the (included) `toc` extension, use: 420 | 421 | ```yaml 422 | markdown_extensions: 423 | - toc: 424 | permalink: True 425 | ``` 426 | 427 | Note that a colon (`:`) must follow the extension name (`toc`) and then on a new 428 | line the option name and value must be indented and separated by a colon. If you 429 | would like to define multiple options for a single extension, each option must be 430 | defined on a separate line: 431 | 432 | ```yaml 433 | markdown_extensions: 434 | - toc: 435 | permalink: True 436 | separator: "_" 437 | ``` 438 | 439 | Add an additional item to the list for each extension. If you have no 440 | configuration options to set for a specific extension, then simply omit options 441 | for that extension: 442 | 443 | ```yaml 444 | markdown_extensions: 445 | - smarty 446 | - toc: 447 | permalink: True 448 | - sane_lists 449 | ``` 450 | 451 | !!! note "See Also:" 452 | The Python-Markdown documentation provides a [list of extensions][exts] 453 | which are available out-of-the-box. For a list of configuration options 454 | available for a given extension, see the documentation for that extension. 455 | 456 | You may also install and use various [third party extensions][3rd]. Consult 457 | the documentation provided by those extensions for installation instructions 458 | and available configuration options. 459 | 460 | **default**: `[]` (an empty list). 461 | 462 | ### plugins 463 | 464 | A list of plugins (with optional configuration settings) to use when building 465 | the site . See the [Plugins] documentation for full details. 466 | 467 | If the `plugins` config setting is defined in the `mkdocs.yml` config file, then 468 | any defaults (such as `search`) are ignored and you need to explicitly re-enable 469 | the defaults if you would like to continue using them: 470 | 471 | ```yaml 472 | plugins: 473 | - search 474 | - your_other_plugin 475 | ``` 476 | 477 | To completely disable all plugins, including any defaults, set the `plugins` 478 | setting to an empty list: 479 | 480 | ```yaml 481 | plugins: [] 482 | ``` 483 | 484 | **default**: `['search']` (the "search" plugin included with MkDocs). 485 | 486 | #### Search 487 | 488 | A search plugin is provided by default with MkDocs which uses [lunr.js] as a 489 | search engine. The following config options are available to alter the behavior 490 | of the search plugin: 491 | 492 | ##### **separator** 493 | 494 | A regular expression which matches the characters used as word separators when 495 | building the index. By default whitespace and the hyphen (`-`) are used. To add 496 | the dot (`.`) as a word separator you might do this: 497 | 498 | ```yaml 499 | plugins: 500 | - search: 501 | separator: '[\s\-\.]+' 502 | ``` 503 | 504 | **default**: `'[\s\-]+'` 505 | 506 | ##### **lang** 507 | 508 | A list of languages to use when building the search index as identified by their 509 | [ISO 639-1] language codes. With [Lunr Languages], the following languages are 510 | supported: 511 | 512 | * `da`: Danish 513 | * `du`: Dutch 514 | * `en`: English 515 | * `fi`: Finnish 516 | * `fr`: French 517 | * `de`: German 518 | * `hu`: Hungarian 519 | * `it`: Italian 520 | * `jp`: Japanese 521 | * `no`: Norwegian 522 | * `pt`: Portuguese 523 | * `ro`: Romanian 524 | * `ru`: Russian 525 | * `es`: Spanish 526 | * `sv`: Swedish 527 | * `th`: Thai 528 | * `tr`: Turkish 529 | 530 | You may [contribute additional languages]. 531 | 532 | !!! Warning 533 | 534 | While search does support using multiple languages together, it is best not 535 | to add additional languages unless you really need them. Each additional 536 | language adds significant bandwidth requirements and uses more browser 537 | resources. Generally it is best to keep each instance of MkDocs to a single 538 | language. 539 | 540 | !!! Note 541 | 542 | Lunr Languages does not currently include support for Chinese or other Asian 543 | languages. However, some users have reported decent results using Japanese. 544 | 545 | **default**: `['en']` 546 | 547 | ##### **prebuild_index** 548 | 549 | Optionally generates a pre-built index of all pages, which provides some 550 | performance improvements for larger sites. Before enabling, check that the 551 | theme you are using explicitly supports using a prebuilt index (the builtin 552 | themes do). The pre-build script requires that [Node.js] be installed and the 553 | command `node` be on the system path. If this feature is enabled and fails for 554 | any reason, a warning is issued. You may use the `--strict` flag when building 555 | to cause such a failure to raise an error instead. 556 | 557 | !!! Note 558 | 559 | On smaller sites, using a pre-built index is not recommended as it creates a 560 | significant increase is bandwidth requirements with little to no noticeable 561 | improvement to your users. However, for larger sites (hundreds of pages), 562 | the bandwidth increase is relatively small and your users will notice a 563 | significant improvement in search performance. 564 | 565 | **default**: `False` 566 | 567 | [custom themes]: custom-themes.md 568 | [variables that are available]: custom-themes.md#template-variables 569 | [pymdk-extensions]: https://python-markdown.github.io/extensions/ 570 | [pymkd]: https://python-markdown.github.io/ 571 | [smarty]: https://python-markdown.github.io/extensions/smarty/ 572 | [exts]: https://python-markdown.github.io/extensions/ 573 | [3rd]: https://github.com/Python-Markdown/markdown/wiki/Third-Party-Extensions 574 | [configuring pages and navigation]: writing-your-docs.md#configure-pages-and-navigation 575 | [theme_dir]: styling-your-docs.md#using-the-theme_dir 576 | [styling your docs]: styling-your-docs.md 577 | [extra_css]: #extra_css 578 | [Plugins]: plugins.md 579 | [lunr.js]: https://lunrjs.com/ 580 | [ISO 639-1]: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes 581 | [Lunr Languages]: https://github.com/MihaiValentin/lunr-languages#lunr-languages----- 582 | [contribute additional languages]: https://github.com/MihaiValentin/lunr-languages/blob/master/CONTRIBUTING.md 583 | [Node.js]: https://nodejs.org/ 584 | -------------------------------------------------------------------------------- /docs/user-guide/custom-themes.md: -------------------------------------------------------------------------------- 1 | # Custom themes 2 | 3 | A guide to creating and distributing custom themes. 4 | 5 | --- 6 | 7 | !!! Note 8 | 9 | If you are looking for third party themes, they are listed in the MkDocs 10 | [community wiki](https://github.com/mkdocs/mkdocs/wiki/MkDocs-Themes). If 11 | you want to share a theme you create, you should list it on the Wiki. 12 | 13 | When creating a new theme, you can either follow the steps in this guide to 14 | create one from scratch or you can download the `mkdocs-basic-theme` as a 15 | basic, yet complete, theme with all the boilerplate required. **You can find 16 | this base theme on [GitHub](https://github.com/mkdocs/mkdocs-basic-theme)**. 17 | It contains detailed comments in the code to describe the different features 18 | and their usage. 19 | 20 | ## Creating a custom theme 21 | 22 | The bare minimum required for a custom theme is a `main.html` [Jinja2 template] 23 | file which is placed in a directory that is *not* a child of the [docs_dir]. 24 | Within `mkdocs.yml`, set the theme.[custom_dir] option to the path of the 25 | directory containing `main.html`. The path should be relative to the 26 | configuration file. For example, given this example project layout: 27 | 28 | ```no-highlight 29 | mkdocs.yml 30 | docs/ 31 | index.md 32 | about.md 33 | custom_theme/ 34 | main.html 35 | ... 36 | ``` 37 | 38 | ... you would include the following settings in `mkdocs.yml` to use the custom theme 39 | directory: 40 | 41 | ```yaml 42 | theme: 43 | name: null 44 | custom_dir: 'custom_theme/' 45 | ``` 46 | 47 | !!! Note 48 | 49 | Generally, when building your own custom theme, the theme.[name] 50 | configuration setting would be set to `null`. However, if the 51 | theme.[custom_dir] configuration value is used in combination with an 52 | existing theme, the theme.[custom_dir] can be used to replace only specific 53 | parts of a built-in theme. For example, with the above layout and if you set 54 | `name: "mkdocs"` then the `main.html` file in the theme.[custom_dir] would 55 | replace the file of the same name in the `mkdocs` theme but otherwise the 56 | `mkdocs` theme would remain unchanged. This is useful if you want to make 57 | small adjustments to an existing theme. 58 | 59 | For more specific information, see [styling your docs]. 60 | 61 | [styling your docs]: ./styling-your-docs.md#using-the-theme-custom_dir 62 | [custom_dir]: ./configuration.md#custom_dir 63 | [name]: ./configuration.md#name 64 | [docs_dir]:./configuration.md#docs_dir 65 | 66 | ## Basic theme 67 | 68 | The simplest `main.html` file is the following: 69 | 70 | ```django 71 | 72 | 73 | 74 | {% if page_title %}{{ page_title }} - {% endif %}{{ site_name }} 75 | 76 | 77 | {{ content }} 78 | 79 | 80 | ``` 81 | 82 | Article content from each page specified in `mkdocs.yml` is inserted using the 83 | `{{ content }}` tag. Style-sheets and scripts can be brought into this theme as 84 | with a normal HTML file. Navbars and tables of contents can also be generated 85 | and included automatically, through the `nav` and `toc` objects, respectively. 86 | If you wish to write your own theme, it is recommended to start with one of 87 | the [built-in themes] and modify it accordingly. 88 | 89 | !!! Note 90 | 91 | As MkDocs uses [Jinja] as its template engine, you have access to all the 92 | power of Jinja, including [template inheritance]. You may notice that the 93 | themes included with MkDocs make extensive use of template inheritance and 94 | blocks, allowing users to easily override small bits and pieces of the 95 | templates from the theme [custom_dir]. Therefore, the built-in themes are 96 | implemented in a `base.html` file, which `main.html` extends. Although not 97 | required, third party template authors are encouraged to follow a similar 98 | pattern and may want to define the same [blocks] as are used in the built-in 99 | themes for consistency. 100 | 101 | [Jinja]: http://jinja.pocoo.org/ 102 | [template inheritance]: http://jinja.pocoo.org/docs/dev/templates/#template-inheritance 103 | [theme_dir]: ./styling-your-docs.md#using-the-theme_dir 104 | [blocks]: ./styling-your-docs.md#overriding-template-blocks 105 | 106 | ## Template Variables 107 | 108 | Each template in a theme is built with a template context. These are the 109 | variables that are available to themes. The context varies depending on the 110 | template that is being built. At the moment templates are either built with 111 | the global context or with a page specific context. The global context is used 112 | for HTML pages that don't represent an individual Markdown document, for 113 | example a 404.html page or search.html. 114 | 115 | ### Global Context 116 | 117 | The following variables are available globally on any template. 118 | 119 | #### config 120 | 121 | The `config` variable is an instance of MkDocs' config object generated from the 122 | `mkdocs.yml` config file. While you can use any config option, some commonly 123 | used options include: 124 | 125 | * [config.site_name](./configuration.md#site_name) 126 | * [config.site_url](./configuration.md#site_url) 127 | * [config.site_author](./configuration.md#site_author) 128 | * [config.site_description](./configuration.md#site_description) 129 | * [config.extra_javascript](./configuration.md#extra_javascript) 130 | * [config.extra_css](./configuration.md#extra_css) 131 | * [config.repo_url](./configuration.md#repo_url) 132 | * [config.repo_name](./configuration.md#repo_name) 133 | * [config.copyright](./configuration.md#copyright) 134 | * [config.google_analytics](./configuration.md#google_analytics) 135 | 136 | #### nav 137 | 138 | The `nav` variable is used to create the navigation for the documentation. The 139 | `nav` object is an iterable of [navigation objects](#navigation-objects) as 140 | defined by the [nav] configuration setting. 141 | 142 | [nav]: configuration.md#nav 143 | 144 | In addition to the iterable of [navigation objects](#navigation-objects), the 145 | `nav` object contains the following attributes: 146 | 147 | ##### nav.homepage 148 | 149 | The [page](#page) object for the homepage of the site. 150 | 151 | ##### nav.pages 152 | 153 | A flat list of all [page](#page) objects contained in the navigation. This list 154 | is not necessarily a complete list of all site pages as it does not contain 155 | pages which are not included in the navigation. This list does match the list 156 | and order of pages used for all "next page" and "previous page" links. For a 157 | list of all pages, use the [pages](#pages) template variable. 158 | 159 | ##### Nav Example 160 | 161 | Following is a basic usage example which outputs the first and second level 162 | navigation as a nested list. 163 | 164 | ```django 165 | {% if nav|length>1 %} 166 |
    167 | {% for nav_item in nav %} 168 | {% if nav_item.children %} 169 |
  • {{ nav_item.title }} 170 |
      171 | {% for nav_item in nav_item.children %} 172 | 175 | {% endfor %} 176 |
    177 |
  • 178 | {% else %} 179 | 182 | {% endif %} 183 | {% endfor %} 184 |
185 | {% endif %} 186 | ``` 187 | 188 | #### base_url 189 | 190 | The `base_url` provides a relative path to the root of the MkDocs project. While 191 | this can be used directly by prepending it to a local relative URL, it is best 192 | to use the [url](#url) template filter, which is smarter about how it applies 193 | `base_url`. 194 | 195 | #### mkdocs_version 196 | 197 | Contains the current MkDocs version. 198 | 199 | #### build_date_utc 200 | 201 | A Python datetime object that represents the date and time the documentation 202 | was built in UTC. This is useful for showing how recently the documentation 203 | was updated. 204 | 205 | #### pages 206 | 207 | A list of [page](#page) objects including *all* pages in the project. The list 208 | is a flat list with all pages sorted alphanumerically by directory and file 209 | name. Note that index pages sort to the top within a directory. This list can 210 | contain pages not included in the global [navigation](#nav) and may not match 211 | the order of pages within that navigation. 212 | 213 | #### page 214 | 215 | In templates which are not rendered from a Markdown source file, the `page` 216 | variable is `None`. In templates which are rendered from a Markdown source file, 217 | the `page` variable contains a `page` object. The same `page` objects are used 218 | as `page` [navigation objects](#navigation-objects) in the global 219 | [navigation](#nav) and in the [pages](#pages) template variable. 220 | 221 | All `page` objects contain the following attributes: 222 | 223 | ##### page.title 224 | 225 | Contains the Title for the current page. 226 | 227 | ##### page.content 228 | 229 | The rendered Markdown as HTML, this is the contents of the documentation. 230 | 231 | ##### page.toc 232 | 233 | An iterable object representing the Table of contents for a page. Each item in 234 | the `toc` is an `AnchorLink` which contains the following attributes: 235 | 236 | * `AnchorLink.title`: The text of the item. 237 | * `AnchorLink.url`: The hash fragment of a URL pointing to the item. 238 | * `AnchorLink.level`: The zero-based level of the item. 239 | * `AnchorLink.children`: An iterable of any child items. 240 | 241 | The following example would display the top two levels of the Table of Contents 242 | for a page. 243 | 244 | ```django 245 | 253 | ``` 254 | 255 | ##### page.meta 256 | 257 | A mapping of the metadata included at the top of the markdown page. In this 258 | example we define a `source` property above the page title. 259 | 260 | ```no-highlight 261 | source: generics.py 262 | mixins.py 263 | 264 | # Page title 265 | 266 | Content... 267 | ``` 268 | 269 | A template can access this metadata for the page with the `meta.source` 270 | variable. This could then be used to link to source files related to the 271 | documentation page. 272 | 273 | ```django 274 | {% for filename in page.meta.source %} 275 | 276 | {{ filename }} 277 | 278 | {% endfor %} 279 | ``` 280 | 281 | ##### page.url 282 | 283 | The URL of the page relative to the MkDocs `site_dir`. It is expected that this 284 | be used with the [url](#url) filter to ensure the URL is relative to the current 285 | page. 286 | 287 | ```django 288 | {{ page.title }} 289 | ``` 290 | 291 | [base_url]: #base_url 292 | 293 | ##### page.abs_url 294 | 295 | The absolute URL of the page from the server root as determined by the value 296 | assigned to the [site_url] configuration setting. The value includes any 297 | subdirectory included in the `site_url`, but not the domain. [base_url] should 298 | not be used with this variable. 299 | 300 | For example, if `site_url: https://example.com/`, then the value of 301 | `page.abs_url` for the page `foo.md` would be `/foo/`. However, if 302 | `site_url: https://example.com/bar/`, then the value of `page.abs_url` for the 303 | page `foo.md` would be `/bar/foo/`. 304 | 305 | [site_url]: ./configuration.md#site_url 306 | 307 | ##### page.canonical_url 308 | 309 | The full, canonical URL to the current page as determined by the value assigned 310 | to the [site_url] configuration setting. The value includes the domain and any 311 | subdirectory included in the `site_url`. [base_url] should not be used with this 312 | variable. 313 | 314 | ##### page.edit_url 315 | 316 | The full URL to the source page in the source repository. Typically used to 317 | provide a link to edit the source page. [base_url] should not be used with this 318 | variable. 319 | 320 | ##### page.is_homepage 321 | 322 | Evaluates to `True` for the homepage of the site and `False` for all other 323 | pages. This can be used in conjunction with other attributes of the `page` 324 | object to alter the behavior. For example, to display a different title 325 | on the homepage: 326 | 327 | ```django 328 | {% if not page.is_homepage %}{{ page.title }} - {% endif %}{{ site_name }} 329 | ``` 330 | 331 | ##### page.previous_page 332 | 333 | The page object for the previous page or `None`. The value will be `None` if the 334 | current page is the first item in the site navigation or if the current page is 335 | not included in the navigation at all. When the value is a page object, the 336 | usage is the same as for `page`. 337 | 338 | ##### page.next_page 339 | 340 | The page object for the next page or `None`. The value will be `None` if the 341 | current page is the last item in the site navigation or if the current page is 342 | not included in the navigation at all. When the value is a page object, the 343 | usage is the same as for `page`. 344 | 345 | ##### page.parent 346 | 347 | The immediate parent of the page in the [site navigation](#nav). `None` if the 348 | page is at the top level. 349 | 350 | ##### page.children 351 | 352 | Pages do not contain children and the attribute is always `None`. 353 | 354 | ##### page.active 355 | 356 | When `True`, indicates that this page is the currently viewed page. Defaults 357 | to `False`. 358 | 359 | ##### page.is_section 360 | 361 | Indicates that the navigation object is a "section" object. Always `False` for 362 | page objects. 363 | 364 | ##### page.is_page 365 | 366 | Indicates that the navigation object is a "page" object. Always `True` for 367 | page objects. 368 | 369 | ##### page.is_link 370 | 371 | Indicates that the navigation object is a "link" object. Always `False` for 372 | page objects. 373 | 374 | ### Navigation Objects 375 | 376 | Navigation objects contained in the [nav](#nav) template variable may be one of 377 | [section](#section) objects, [page](#page) objects, and [link](#link) objects. 378 | While section objects may contain nested navigation objects, pages and links do 379 | not. 380 | 381 | Page objects are the full page object as used for the current [page](#page) with 382 | all of the same attributes available. Section and Link objects contain a subset 383 | of those attributes as defined below: 384 | 385 | #### Section 386 | 387 | A `section` navigation object defines a named section in the navigation and 388 | contains a list of child navigation objects. Note that sections do not contain 389 | URLs and are not links of any kind. However, by default, MkDocs sorts index 390 | pages to the top and the first child might be used as the URL for a section if a 391 | theme choses to do so. 392 | 393 | The following attributes are available on `section` objects: 394 | 395 | ##### section.title 396 | 397 | The title of the section. 398 | 399 | ##### section.parent 400 | 401 | The immediate parent of the section or `None` if the section is at the top 402 | level. 403 | 404 | ##### section.children 405 | 406 | An iterable of all child navigation objects. Children may include nested 407 | sections, pages and links. 408 | 409 | ##### section.active 410 | 411 | When `True`, indicates that a child page of this section is the current page and 412 | can be used to highlight the section as the currently viewed section. Defaults 413 | to `False`. 414 | 415 | ##### section.is_section 416 | 417 | Indicates that the navigation object is a "section" object. Always `True` for 418 | section objects. 419 | 420 | ##### section.is_page 421 | 422 | Indicates that the navigation object is a "page" object. Always `False` for 423 | section objects. 424 | 425 | ##### section.is_link 426 | 427 | Indicates that the navigation object is a "link" object. Always `False` for 428 | section objects. 429 | 430 | #### Link 431 | 432 | A `link` navigation object contains a link which does not point to an internal 433 | MkDocs page. The following attributes are available on `link` objects: 434 | 435 | ##### link.title 436 | 437 | The title of the link. This would generally be used as the label of the link. 438 | 439 | ##### link.url 440 | 441 | The URL that the link points to. The URL should always be an absolute URLs and 442 | should not need to have `base_url` prepened. 443 | 444 | ##### link.parent 445 | 446 | The immediate parent of the link. `None` if the link is at the top level. 447 | 448 | ##### link.children 449 | 450 | Links do not contain children and the attribute is always `None`. 451 | 452 | ##### link.active 453 | 454 | External links cannot be "active" and the attribute is always `False`. 455 | 456 | ##### link.is_section 457 | 458 | Indicates that the navigation object is a "section" object. Always `False` for 459 | link objects. 460 | 461 | ##### link.is_page 462 | 463 | Indicates that the navigation object is a "page" object. Always `False` for 464 | link objects. 465 | 466 | ##### link.is_link 467 | 468 | Indicates that the navigation object is a "link" object. Always `True` for 469 | link objects. 470 | 471 | ### Extra Context 472 | 473 | Additional variables can be passed to the template with the 474 | [`extra`](/user-guide/configuration.md#extra) configuration option. This is a 475 | set of key value pairs that can make custom templates far more flexible. 476 | 477 | For example, this could be used to include the project version of all pages 478 | and a list of links related to the project. This can be achieved with the 479 | following `extra` configuration: 480 | 481 | ```yaml 482 | extra: 483 | version: 0.13.0 484 | links: 485 | - https://github.com/mkdocs 486 | - https://docs.readthedocs.org/en/latest/builds.html#mkdocs 487 | - https://www.mkdocs.org/ 488 | ``` 489 | 490 | And then displayed with this HTML in the custom theme. 491 | 492 | ```django 493 | {{ config.extra.version }} 494 | 495 | {% if config.extra.links %} 496 |
    497 | {% for link in config.extra.links %} 498 |
  • {{ link }}
  • 499 | {% endfor %} 500 |
501 | {% endif %} 502 | ``` 503 | 504 | ## Template Filters 505 | 506 | In addition to Jinja's default filters, the following custom filters are 507 | available to use in MkDocs templates: 508 | 509 | ### url 510 | 511 | Normalizes a URL. Absolute URLs are passed through unaltered. If the URL is 512 | relative and the template context includes a page object, then the URL is 513 | returned relative to the page object. Otherwise, the URL is returned with 514 | [base_url](#base_url) prepended. 515 | 516 | ```django 517 | {{ page.title }} 518 | ``` 519 | 520 | ### tojson 521 | 522 | Safety convert a Python object to a value in a JavaScript script. 523 | 524 | ```django 525 | 528 | ``` 529 | 530 | ## Search and themes 531 | 532 | As of MkDocs version *0.17* client side search support has been added to MkDocs 533 | via the `search` plugin. A theme needs to provide a few things for the plugin to 534 | work with the theme. 535 | 536 | While the `search` plugin is activated by default, users can disable the plugin 537 | and themes should account for this. It is recommended that theme templates wrap 538 | search specific markup with a check for the plugin: 539 | 540 | ```django 541 | {% if 'search' in config['plugins'] %} 542 | search stuff here... 543 | {% endif %} 544 | ``` 545 | 546 | At its most basic functionality, the search plugin will simply provide an index 547 | file which is no more than a JSON file containing the content of all pages. 548 | The theme would need to implement its own search functionality client-side. 549 | However, with a few settings and the necessary templates, the plugin can provide 550 | a complete functioning client-side search tool based on [lunr.js]. 551 | 552 | The following HTML needs to be added to the theme so that the provided 553 | JavaScript is able to properly load the search scripts and make relative links 554 | to the search results from the current page. 555 | 556 | ```django 557 | 558 | ``` 559 | 560 | With properly configured settings, the following HTML in a template will add a 561 | full search implementation to your theme. 562 | 563 | ```django 564 |

Search Results

565 | 566 |
567 | 568 |
569 | 570 |
571 | Sorry, page not found. 572 |
573 | ``` 574 | 575 | The JavaScript in the plugin works by looking for the specific ID's used in the 576 | above HTML. The form input for the user to type the search query must be 577 | identified with `id="mkdocs-search-query"` and the div where the results will be 578 | placed must be identified with `id="mkdocs-search-results"`. 579 | 580 | The plugin supports the following options being set in the [theme's 581 | configuration file], `mkdocs_theme.yml`: 582 | 583 | ### include_search_page 584 | 585 | Determines whether the search plugin expects the theme to provide a dedicated 586 | search page via a template located at `search/search.html`. 587 | 588 | When `include_search_page` is set to `true`, the search template will be built 589 | and available at `search/search.html`. This method is used by the `readthedocs` 590 | theme. 591 | 592 | When `include_search_page` is set to `false` or not defined, it is expected that 593 | the theme provide some other mechanisms for displaying search results. For 594 | example, the `mkdocs` theme displays results on any page via a modal. 595 | 596 | ### search_index_only 597 | 598 | Determines whether the search plugin should only generate a search index or a 599 | complete search solution. 600 | 601 | When `search_index_only` is set to `false`, then the search plugin modifies the 602 | Jinja environment by adding its own `templates` directory (with a lower 603 | precedence than the theme) and adds its scripts to the `extra_javascript` config 604 | setting. 605 | 606 | When `search_index_only` is set to `true` or not defined, the search plugin 607 | makes no modifications to the Jinja environment. A complete solution using the 608 | provided index file is the responsibility of the theme. 609 | 610 | The search index is written to a JSON file at `search/search_index.json` in the 611 | [site_dir]. The JSON object contained within the file may contain up to three 612 | objects. 613 | 614 | ```json 615 | { 616 | config: {...}, 617 | data: [...], 618 | index: {...} 619 | } 620 | ``` 621 | 622 | If present, the `config` object contains the key/value pairs of config options 623 | defined for the plugin in the user's `mkdocs.yml` config file under 624 | `plugings.search`. The `config` object was new in MkDocs version *1.0*. 625 | 626 | The `data` object contains a list of document objects. Each document object is 627 | made up of a `location` (URL), a `title`, and `text` which can be used to create 628 | a search index and/or display search results. 629 | 630 | If present, the `index` object contains a pre-built index which offers 631 | performance improvements for larger sites. Note that the pre-built index is only 632 | created if the user explicitly enables the [prebuild_index] config option. 633 | Themes should expect the index to not be present, but can choose to use the 634 | index when it is available. The `index` object was new in MkDocs version *1.0*. 635 | 636 | [Jinja2 template]: http://jinja.pocoo.org/docs/dev/ 637 | [built-in themes]: https://github.com/mkdocs/mkdocs/tree/master/mkdocs/themes 638 | [theme's configuration file]: #theme-configuration 639 | [lunr.js]: https://lunrjs.com/ 640 | [site_dir]: configuration.md#site_dir 641 | [prebuild_index]: configuration.md#prebuild_index 642 | 643 | ## Packaging Themes 644 | 645 | MkDocs makes use of [Python packaging] to distribute themes. This comes with a 646 | few requirements. 647 | 648 | To see an example of a package containing one theme, see the [MkDocs Bootstrap 649 | theme] and to see a package that contains many themes, see the [MkDocs 650 | Bootswatch theme]. 651 | 652 | !!! Note 653 | 654 | It is not strictly necessary to package a theme, as the entire theme 655 | can be contained in the `custom_dir`. If you have created a "one-off theme," 656 | that should be sufficient. However, if you intend to distribute your theme 657 | for others to use, packaging the theme has some advantages. By packaging 658 | your theme, your users can more easily install it and they can then take 659 | advantage of the [custom_dir] to make tweaks to your theme to better suit 660 | their needs. 661 | 662 | [Python packaging]: https://packaging.python.org/en/latest/ 663 | [MkDocs Bootstrap theme]: https://mkdocs.github.io/mkdocs-bootstrap/ 664 | [MkDocs Bootswatch theme]: https://mkdocs.github.io/mkdocs-bootswatch/ 665 | 666 | ### Package Layout 667 | 668 | The following layout is recommended for themes. Two files at the top level 669 | directory called `MANIFEST.in` and `setup.py` beside the theme directory which 670 | contains an empty `__init__.py` file, a theme configuration file 671 | (`mkdocs-theme.yml`), and your template and media files. 672 | 673 | ```no-highlight 674 | . 675 | |-- MANIFEST.in 676 | |-- theme_name 677 | | |-- __init__.py 678 | | |-- mkdocs-theme.yml 679 | | |-- main.html 680 | | |-- styles.css 681 | `-- setup.py 682 | ``` 683 | 684 | The `MANIFEST.in` file should contain the following contents but with 685 | theme_name updated and any extra file extensions added to the include. 686 | 687 | ```no-highlight 688 | recursive-include theme_name *.ico *.js *.css *.png *.html *.eot *.svg *.ttf *.woff 689 | recursive-exclude * __pycache__ 690 | recursive-exclude * *.py[co] 691 | ``` 692 | 693 | The `setup.py` should include the following text with the modifications 694 | described below. 695 | 696 | ```python 697 | from setuptools import setup, find_packages 698 | 699 | VERSION = '0.0.1' 700 | 701 | 702 | setup( 703 | name="mkdocs-themename", 704 | version=VERSION, 705 | url='', 706 | license='', 707 | description='', 708 | author='', 709 | author_email='', 710 | packages=find_packages(), 711 | include_package_data=True, 712 | entry_points={ 713 | 'mkdocs.themes': [ 714 | 'themename = theme_name', 715 | ] 716 | }, 717 | zip_safe=False 718 | ) 719 | ``` 720 | 721 | Fill in the URL, license, description, author and author email address. 722 | 723 | The name should follow the convention `mkdocs-themename` (like `mkdocs- 724 | bootstrap` and `mkdocs-bootswatch`), starting with MkDocs, using hyphens to 725 | separate words and including the name of your theme. 726 | 727 | Most of the rest of the file can be left unedited. The last section we need to 728 | change is the entry_points. This is how MkDocs finds the theme(s) you are 729 | including in the package. The name on the left is the one that users will use 730 | in their mkdocs.yml and the one on the right is the directory containing your 731 | theme files. 732 | 733 | The directory you created at the start of this section with the main.html file 734 | should contain all of the other theme files. The minimum requirement is that 735 | it includes a `main.html` for the theme. It **must** also include a 736 | `__init__.py` file which should be empty, this file tells Python that the 737 | directory is a package. 738 | 739 | ### Theme Configuration 740 | 741 | A packaged theme is required to include a configuration file named 742 | `mkdocs_theme.yml` which is placed in the root of your template files. The file 743 | should contain default configuration options for the theme. However, if the 744 | theme offers no configuration options, the file is still required and can be 745 | left blank. 746 | 747 | The theme author is free to define any arbitrary options deemed necessary and 748 | those options will be made available in the templates to control behavior. 749 | For example, a theme might want to make a sidebar optional and include the 750 | following in the `mkdocs_theme.yml` file: 751 | 752 | ```yaml 753 | show_sidebar: true 754 | ``` 755 | 756 | Then in a template, that config option could be referenced: 757 | 758 | ```django 759 | {% if config.theme.show_sidebar %} 760 | 761 | {% endif %} 762 | ``` 763 | 764 | And the user could override the default in their project's `mkdocs.yml` config 765 | file: 766 | 767 | ```yaml 768 | theme: 769 | name: themename 770 | show_sidebar: false 771 | ``` 772 | 773 | In addition to arbitrary options defined by the theme, MkDocs defines a few 774 | special options which alters its behavior: 775 | 776 | !!! block "" 777 | 778 | #### static_templates 779 | 780 | This option mirrors the [theme] config option of the same name and allows 781 | some defaults to be set by the theme. Note that while the user can add 782 | templates to this list, the user cannot remove templates included in the 783 | theme's config. 784 | 785 | #### extends 786 | 787 | Defines a parent theme that this theme inherits from. The value should be 788 | the string name of the parent theme. Normal Jinja inheritance rules apply. 789 | 790 | Plugins may also define some options which allow the theme to inform a plugin 791 | about which set of plugin options it expects. See the documentation for any 792 | plugins you may wish to support in your theme. 793 | 794 | ### Distributing Themes 795 | 796 | With the above changes, your theme should now be ready to install. This can be 797 | done with pip, using `pip install .` if you are still in the same directory as 798 | the setup.py. 799 | 800 | Most Python packages, including MkDocs, are distributed on PyPI. To do this, 801 | you should run the following command. 802 | 803 | ```no-highlight 804 | python setup.py register 805 | ``` 806 | 807 | If you don't have an account setup, you should be prompted to create one. 808 | 809 | For a much more detailed guide, see the official Python packaging 810 | documentation for [Packaging and Distributing Projects]. 811 | 812 | [Packaging and Distributing Projects]: https://packaging.python.org/en/latest/distributing/ 813 | [theme]: ./configuration.md#theme 814 | -------------------------------------------------------------------------------- /docs/user-guide/deploying-your-docs.md: -------------------------------------------------------------------------------- 1 | # Deploying your docs 2 | 3 | A basic guide to deploying your docs to various hosting providers 4 | 5 | --- 6 | 7 | ## GitHub Pages 8 | 9 | If you host the source code for a project on [GitHub], you can easily use 10 | [GitHub Pages] to host the documentation for your project. There are two basic 11 | types of GitHub Pages sites: [Project Pages] sites, and [User and Organization 12 | Pages] sites. They are nearly identical but have some important differences, 13 | which require a different work flow when deploying. 14 | 15 | ### Project Pages 16 | 17 | Project Pages sites are simpler as the site files get deployed to a branch 18 | within the project repository (`gh-pages` by default). After you `checkout` the 19 | primary working branch (usually `master`) of the git repository where you 20 | maintain the source documentation for your project, run the following command: 21 | 22 | ```sh 23 | mkdocs gh-deploy 24 | ``` 25 | 26 | That's it! Behind the scenes, MkDocs will build your docs and use the 27 | [ghp-import] tool to commit them to the `gh-pages` branch and push the 28 | `gh-pages` branch to GitHub. 29 | 30 | Use `mkdocs gh-deploy --help` to get a full list of options available for the 31 | `gh-deploy` command. 32 | 33 | Be aware that you will not be able to review the built site before it is pushed 34 | to GitHub. Therefore, you may want to verify any changes you make to the docs 35 | beforehand by using the `build` or `serve` commands and reviewing the built 36 | files locally. 37 | 38 | !!! warning 39 | 40 | You should never edit files in your pages repository by hand if you're using 41 | the `gh-deploy` command because you will lose your work the next time you 42 | run the command. 43 | 44 | ### Organization and User Pages 45 | 46 | User and Organization Pages sites are not tied to a specific project, and the 47 | site files are deployed to the `master` branch in a dedicated repository named 48 | with the GitHub account name. Therefore, you need working copies of two 49 | repositories on our local system. For example, consider the following file 50 | structure: 51 | 52 | ```no-highlight 53 | my-project/ 54 | mkdocs.yml 55 | docs/ 56 | orgname.github.io/ 57 | ``` 58 | 59 | After making and verifying updates to your project you need to change 60 | directories to the `orgname.github.io` repository and call the 61 | `mkdocs gh-deploy` command from there: 62 | 63 | ```sh 64 | cd ../orgname.github.io/ 65 | mkdocs gh-deploy --config-file ../my-project/mkdocs.yml --remote-branch master 66 | ``` 67 | 68 | Note that you need to explicitly point to the `mkdocs.yml` configuration file as 69 | it is no longer in the current working directory. You also need to inform the 70 | deploy script to commit to the `master` branch. You may override the default 71 | with the [remote_branch] configuration setting, but if you forget to change 72 | directories before running the deploy script, it will commit to the `master` 73 | branch of your project, which you probably don't want. 74 | 75 | Be aware that you will not be able to review the built site before it is pushed 76 | to GitHub. Therefore, you may want to verify any changes you make to the docs 77 | beforehand by using the `build` or `serve` commands and reviewing the built 78 | files locally. 79 | 80 | !!! warning 81 | 82 | You should never edit files in your pages repository by hand if you're using 83 | the `gh-deploy` command because you will lose your work the next time you 84 | run the command. 85 | 86 | ### Custom Domains 87 | 88 | GitHub Pages includes support for using a [Custom Domain] for your site. In 89 | addition to the steps documented by GitHub, you need to take one additional step 90 | so that MkDocs will work with your custom domain. You need to add a `CNAME` file 91 | to the root of your [docs_dir]. The file must contain a single bare domain or 92 | subdomain on a single line (see MkDocs' own [CNAME file] as an example). You may 93 | create the file manually, or use GitHub's web interface to set up the custom 94 | domain (under Settings / Custom Domain). If you use the web interface, GitHub 95 | will create the `CNAME` file for you and save it to the root of your "pages" 96 | branch. So that the file does not get removed the next time you deploy, you need 97 | to copy the file to your `docs_dir`. With the file properly included in your 98 | `docs_dir`, MkDocs will include the file in your built site and push it to your 99 | "pages" branch each time you run the `gh-deploy` command. 100 | 101 | If you are having problems getting a custom domain to work, see GitHub's 102 | documentation on [Troubleshooting custom domains]. 103 | 104 | [GitHub]: https://github.com/ 105 | [GitHub Pages]: https://pages.github.com/ 106 | [Project Pages]: https://help.github.com/articles/user-organization-and-project-pages/#project-pages-sites 107 | [User and Organization Pages]: https://help.github.com/articles/user-organization-and-project-pages/#user-and-organization-pages-sites 108 | [ghp-import]: https://github.com/davisp/ghp-import 109 | [remote_branch]: ./configuration.md#remote_branch 110 | [Custom Domain]: https://help.github.com/articles/adding-or-removing-a-custom-domain-for-your-github-pages-site 111 | [docs_dir]: ./configuration.md#docs_dir 112 | [CNAME file]: https://github.com/mkdocs/mkdocs/blob/master/docs/CNAME 113 | [Troubleshooting custom domains]: https://help.github.com/articles/troubleshooting-custom-domains/ 114 | 115 | ## Read the Docs 116 | 117 | [Read the Docs][rtd] offers free documentation hosting. You can import your docs 118 | using any major version control system, including Mercurial, Git, Subversion, 119 | and Bazaar. Read the Docs supports MkDocs out-of-the-box. Follow the 120 | [instructions] on their site to arrange the files in your repository properly, 121 | create an account and point it at your publicly hosted repository. If properly 122 | configured, your documentation will update each time you push commits to your 123 | public repository. 124 | 125 | !!! note 126 | 127 | To benefit from all of the [features] offered by Read the Docs, you will need 128 | to use the [Read the Docs theme][theme] which ships with MkDocs. The various 129 | themes which may be referenced in Read the Docs' documentation are Sphinx 130 | specific themes and will not work with MkDocs. 131 | 132 | [rtd]: https://readthedocs.org/ 133 | [instructions]: https://read-the-docs.readthedocs.io/en/latest/getting_started.html#in-markdown 134 | [features]: http://read-the-docs.readthedocs.io/en/latest/features.html 135 | [theme]: ./styling-your-docs.md#readthedocs 136 | 137 | ## Other Providers 138 | 139 | Any hosting provider which can serve static files can be used to serve 140 | documentation generated by MkDocs. While it would be impossible to document how 141 | to upload the docs to every hosting provider out there, the following guidelines 142 | should provide some general assistance. 143 | 144 | When you build your site (using the `mkdocs build` command), all of the files 145 | are written to the directory assigned to the [site_dir] configuration option 146 | (defaults to `"site"`) in your `mkdocs.yaml` config file. Generally, you will 147 | simply need to copy the contents of that directory to the root directory of your 148 | hosting provider's server. Depending on your hosting provider's setup, you may 149 | need to use a graphical or command line [ftp], [ssh] or [scp] client to transfer 150 | the files. 151 | 152 | For example, a typical set of commands from the command line might look 153 | something like this: 154 | 155 | ```sh 156 | mkdocs build 157 | scp -r ./site user@host:/path/to/server/root 158 | ``` 159 | 160 | Of course, you will need to replace `user` with the username you have with your 161 | hosting provider and `host` with the appropriate domain name. Additionally, you 162 | will need to adjust the `/path/to/server/root` to match the configuration of 163 | your hosts' file system. 164 | 165 | [ftp]: https://en.wikipedia.org/wiki/File_Transfer_Protocol 166 | [ssh]: https://en.wikipedia.org/wiki/Secure_Shell 167 | [scp]: https://en.wikipedia.org/wiki/Secure_copy 168 | 169 | See your host's documentation for specifics. You will likely want to search 170 | their documentation for "ftp" or "uploading site". 171 | 172 | ## 404 Pages 173 | 174 | When MkDocs builds the documentation it will include a 404.html file in the 175 | [build directory][site_dir]. This file will be automatically used when 176 | deploying to [GitHub](#github-pages) but only on a custom domain. Other web 177 | servers may be configured to use it but the feature won't always be available. 178 | See the documentation for your server of choice for more information. 179 | 180 | [site_dir]: ./configuration.md#site_dir 181 | -------------------------------------------------------------------------------- /docs/user-guide/plugins.md: -------------------------------------------------------------------------------- 1 | # MkDocs Plugins 2 | 3 | A Guide to installing, using and creating MkDocs Plugins 4 | 5 | --- 6 | 7 | ## Installing Plugins 8 | 9 | Before a plugin can be used, it must be installed on the system. If you are 10 | using a plugin which comes with MkDocs, then it was installed when you installed 11 | MkDocs. However, to install third party plugins, you need to determine the 12 | appropriate package name and install it using `pip`: 13 | 14 | pip install mkdocs-foo-plugin 15 | 16 | Once a plugin has been successfully installed, it is ready to use. It just needs 17 | to be [enabled](#using-plugins) in the configuration file. 18 | 19 | ## Using Plugins 20 | 21 | The [`plugins`][config] configuration option should contain a list of plugins to 22 | use when building the site. Each "plugin" must be a string name assigned to the 23 | plugin (see the documentation for a given plugin to determine its "name"). A 24 | plugin listed here must already be [installed](#installing-plugins). 25 | 26 | ```yaml 27 | plugins: 28 | - search 29 | ``` 30 | 31 | Some plugins may provide configuration options of their own. If you would like 32 | to set any configuration options, then you can nest a key/value mapping 33 | (`option_name: option value`) of any options that a given plugin supports. Note 34 | that a colon (`:`) must follow the plugin name and then on a new line the option 35 | name and value must be indented and separated by a colon. If you would like to 36 | define multiple options for a single plugin, each option must be defined on a 37 | separate line. 38 | 39 | ```yaml 40 | plugins: 41 | - search: 42 | lang: en 43 | foo: bar 44 | ``` 45 | 46 | For information regarding the configuration options available for a given plugin, 47 | see that plugin's documentation. 48 | 49 | For a list of default plugins and how to override them, see the 50 | [configuration][config] documentation. 51 | 52 | ## Developing Plugins 53 | 54 | Like MkDocs, plugins must be written in Python. It is generally expected that 55 | each plugin would be distributed as a separate Python module, although it is 56 | possible to define multiple plugins in the same module. At a minimum, a MkDocs 57 | Plugin must consist of a [BasePlugin] subclass and an [entry point] which 58 | points to it. 59 | 60 | ### BasePlugin 61 | 62 | A subclass of `mkdocs.plugins.BasePlugin` should define the behavior of the plugin. 63 | The class generally consists of actions to perform on specific events in the build 64 | process as well as a configuration scheme for the plugin. 65 | 66 | All `BasePlugin` subclasses contain the following attributes: 67 | 68 | #### config_scheme 69 | 70 | : A tuple of configuration validation instances. Each item must consist of a 71 | two item tuple in which the first item is the string name of the 72 | configuration option and the second item is an instance of 73 | `mkdocs.config.config_options.BaseConfigOption` or any of its subclasses. 74 | 75 | For example, the following `config_scheme` defines three configuration options: `foo`, which accepts a string; `bar`, which accepts an integer; and `baz`, which accepts a boolean value. 76 | 77 | class MyPlugin(mkdocs.plugins.BasePlugin): 78 | config_scheme = ( 79 | ('foo', mkdocs.config.config_options.Type(mkdocs.utils.string_types, default='a default value')), 80 | ('bar', mkdocs.config.config_options.Type(int, default=0)), 81 | ('baz', mkdocs.config.config_options.Type(bool, default=True)) 82 | ) 83 | 84 | When the user's configuration is loaded, the above scheme will be used to 85 | validate the configuration and fill in any defaults for settings not 86 | provided by the user. The validation classes may be any of the classes 87 | provided in `mkdocs.config.config_options` or a third party subclass defined 88 | in the plugin. 89 | 90 | Any settings provided by the user which fail validation or are not defined 91 | in the `config_scheme` will raise a `mkdocs.config.base.ValidationError`. 92 | 93 | #### config 94 | 95 | : A dictionary of configuration options for the plugin, which is populated by 96 | the `load_config` method after configuration validation has completed. Use 97 | this attribute to access options provided by the user. 98 | 99 | def on_pre_build(self, config): 100 | if self.config['bool_option']: 101 | # implement "bool_option" functionality here... 102 | 103 | All `BasePlugin` subclasses contain the following method(s): 104 | 105 | #### load_config(options) 106 | 107 | : Loads configuration from a dictionary of options. Returns a tuple of 108 | `(errors, warnings)`. This method is called by MkDocs during configuration 109 | validation and should not need to be called by the plugin. 110 | 111 | #### on_<event_name>() 112 | 113 | : Optional methods which define the behavior for specific [events]. The plugin 114 | should define its behavior within these methods. Replace `` with 115 | the actual name of the event. For example, the `pre_build` event would be 116 | defined in the `on_pre_build` method. 117 | 118 | Most events accept one positional argument and various keyword arguments. It 119 | is generally expected that the positional argument would be modified (or 120 | replaced) by the plugin and returned. If nothing is returned (the method 121 | returns `None`), then the original, unmodified object is used. The keyword 122 | arguments are simply provided to give context and/or supply data which may 123 | be used to determine how the positional argument should be modified. It is 124 | good practice to accept keyword arguments as `**kwargs`. In the event that 125 | additional keywords are provided to an event in a future version of MkDocs, 126 | there will be no need to alter your plugin. 127 | 128 | For example, the following event would add an additional static_template to 129 | the theme config: 130 | 131 | class MyPlugin(BasePlugin): 132 | def on_config(self, config, **kwargs): 133 | config['theme'].static_templates.add('my_template.html') 134 | return config 135 | 136 | ### Events 137 | 138 | There are three kinds of events: [Global Events], [Page Events] and 139 | [Template Events]. 140 | 141 | #### Global Events 142 | 143 | Global events are called once per build at either the beginning or end of the 144 | build process. Any changes made in these events will have a global effect on the 145 | entire site. 146 | 147 | ##### on_serve 148 | 149 | : The `serve` event is only called when the `serve` command is used during 150 | development. It is passed the `Server` instance which can be modified before 151 | it is activated. For example, additional files or directories could be added 152 | to the list of "watched" files for auto-reloading. 153 | 154 | Parameters: 155 | : __server:__ `livereload.Server` instance 156 | : __config:__ global configuration object 157 | 158 | Returns: 159 | : `livereload.Server` instance 160 | 161 | ##### on_config 162 | 163 | : The `config` event is the first event called on build and is run immediately 164 | after the user configuration is loaded and validated. Any alterations to the 165 | config should be made here. 166 | 167 | Parameters: 168 | : __config:__ global configuration object 169 | 170 | Returns: 171 | : global configuration object 172 | 173 | ##### on_pre_build 174 | 175 | : The `pre_build` event does not alter any variables. Use this event to call 176 | pre-build scripts. 177 | 178 | Parameters: 179 | : __config:__ global configuration object 180 | 181 | ##### on_files 182 | 183 | : The `files` event is called after the files collection is populated from the 184 | `docs_dir`. Use this event to add, remove, or alter files in the 185 | collection. Note that Page objects have not yet been associated with the 186 | file objects in the collection. Use [Page Events] to manipulate page 187 | specific data. 188 | 189 | Parameters: 190 | : __files:__ global files collection 191 | : __config:__ global configuration object 192 | 193 | Returns: 194 | : global files collection 195 | 196 | ##### on_nav 197 | 198 | : The `nav` event is called after the site navigation is created and can 199 | be used to alter the site navigation. 200 | 201 | Parameters: 202 | : __nav:__ global navigation object 203 | : __config:__ global configuration object 204 | : __files:__ global files collection 205 | 206 | Returns: 207 | : global navigation object 208 | 209 | ##### on_env 210 | 211 | : The `env` event is called after the Jinja template environment is created 212 | and can be used to alter the Jinja environment. 213 | 214 | Parameters: 215 | : __env:__ global Jinja environment 216 | : __config:__ global configuration object 217 | : __site_navigation:__ global navigation object 218 | 219 | Returns: 220 | : global Jinja Environment 221 | 222 | ##### on_post_build 223 | 224 | : The `post_build` event does not alter any variables. Use this event to call 225 | post-build scripts. 226 | 227 | Parameters: 228 | : __config:__ global configuration object 229 | 230 | #### Template Events 231 | 232 | Template events are called once for each non-page template. Each template event 233 | will be called for each template defined in the [extra_templates] config setting 234 | as well as any [static_templates] defined in the theme. All template events are 235 | called after the [env] event and before any [page events]. 236 | 237 | ##### on_pre_template 238 | 239 | : The `pre_template` event is called immediately after the subject template is 240 | loaded and can be used to alter the content of the template. 241 | 242 | Parameters: 243 | : __template__: the template contents as string 244 | : __template_name__: string filename of template 245 | : __config:__ global configuration object 246 | 247 | Returns: 248 | : template contents as string 249 | 250 | ##### on_template_context 251 | 252 | : The `template_context` event is called immediately after the context is created 253 | for the subject template and can be used to alter the context for that specific 254 | template only. 255 | 256 | Parameters: 257 | : __context__: dict of template context variables 258 | : __template_name__: string filename of template 259 | : __config:__ global configuration object 260 | 261 | Returns: 262 | : dict of template context variables 263 | 264 | ##### on_post_template 265 | 266 | : The `post_template` event is called after the template is rendered, but before 267 | it is written to disc and can be used to alter the output of the template. 268 | If an empty string is returned, the template is skipped and nothing is is 269 | written to disc. 270 | 271 | Parameters: 272 | : __output_content__: output of rendered template as string 273 | : __template_name__: string filename of template 274 | : __config:__ global configuration object 275 | 276 | Returns: 277 | : output of rendered template as string 278 | 279 | #### Page Events 280 | 281 | Page events are called once for each Markdown page included in the site. All 282 | page events are called after the [post_template] event and before the 283 | [post_build] event. 284 | 285 | ##### on_pre_page 286 | 287 | : The `pre_page` event is called before any actions are taken on the subject 288 | page and can be used to alter the `Page` instance. 289 | 290 | Parameters: 291 | : __page:__ `mkdocs.nav.Page` instance 292 | : __config:__ global configuration object 293 | : __site_navigation:__ global navigation object 294 | 295 | Returns: 296 | : `mkdocs.nav.Page` instance 297 | 298 | ##### on_page_read_source 299 | 300 | : The `on_page_read_source` event can replace the default mechanism to read 301 | the contents of a page's source from the filesystem. 302 | 303 | Parameters: 304 | : __page:__ `mkdocs.nav.Page` instance 305 | : __config:__ global configuration object 306 | 307 | Returns: 308 | : The raw source for a page as unicode string. If `None` is returned, the 309 | default loading from a file will be performed. 310 | 311 | ##### on_page_markdown 312 | 313 | : The `page_markdown` event is called after the page's markdown is loaded 314 | from file and can be used to alter the Markdown source text. The meta- 315 | data has been stripped off and is available as `page.meta` at this point. 316 | 317 | Parameters: 318 | : __markdown:__ Markdown source text of page as string 319 | : __page:__ `mkdocs.nav.Page` instance 320 | : __config:__ global configuration object 321 | : __site_navigation:__ global navigation object 322 | 323 | Returns: 324 | : Markdown source text of page as string 325 | 326 | ##### on_page_content 327 | 328 | : The `page_content` event is called after the Markdown text is rendered to 329 | HTML (but before being passed to a template) and can be used to alter the 330 | HTML body of the page. 331 | 332 | Parameters: 333 | : __html:__ HTML rendered from Markdown source as string 334 | : __page:__ `mkdocs.nav.Page` instance 335 | : __config:__ global configuration object 336 | : __site_navigation:__ global navigation object 337 | 338 | Returns: 339 | : HTML rendered from Markdown source as string 340 | 341 | ##### on_page_context 342 | 343 | : The `page_context` event is called after the context for a page is created 344 | and can be used to alter the context for that specific page only. 345 | 346 | Parameters: 347 | : __context__: dict of template context variables 348 | : __page:__ `mkdocs.nav.Page` instance 349 | : __config:__ global configuration object 350 | : __site_navigation:__ global navigation object 351 | 352 | Returns: 353 | : dict of template context variables 354 | 355 | ##### on_post_page 356 | 357 | : The `post_template` event is called after the template is rendered, but 358 | before it is written to disc and can be used to alter the output of the 359 | page. If an empty string is returned, the page is skipped and nothing is 360 | written to disc. 361 | 362 | Parameters: 363 | : __output_content:__ output of rendered template as string 364 | : __page:__ `mkdocs.nav.Page` instance 365 | : __config:__ global configuration object 366 | : __site_navigation:__ global navigation object 367 | 368 | Returns: 369 | : output of rendered template as string 370 | 371 | ### Entry Point 372 | 373 | Plugins need to be packaged as Python libraries (distributed on PyPI separate 374 | from MkDocs) and each must register as a Plugin via a setuptools entry_point. 375 | Add the following to your `setup.py` script: 376 | 377 | ```python 378 | entry_points={ 379 | 'mkdocs.plugins': [ 380 | 'pluginname = path.to.some_plugin:SomePluginClass', 381 | ] 382 | } 383 | ``` 384 | 385 | The `pluginname` would be the name used by users (in the config file) and 386 | `path.to.some_plugin:SomePluginClass` would be the importable plugin itself 387 | (`from path.to.some_plugin import SomePluginClass`) where `SomePluginClass` is a 388 | subclass of [BasePlugin] which defines the plugin behavior. Naturally, multiple 389 | Plugin classes could exist in the same module. Simply define each as a separate 390 | entry_point. 391 | 392 | ```python 393 | entry_points={ 394 | 'mkdocs.plugins': [ 395 | 'featureA = path.to.my_plugins:PluginA', 396 | 'featureB = path.to.my_plugins:PluginB' 397 | ] 398 | } 399 | ``` 400 | 401 | Note that registering a plugin does not activate it. The user still needs to 402 | tell MkDocs to use if via the config. 403 | 404 | [BasePlugin]:#baseplugin 405 | [config]: configuration.md#plugins 406 | [entry point]: #entry-point 407 | [env]: #on_env 408 | [events]: #events 409 | [extra_templates]: configuration.md#extra_templates 410 | [Global Events]: #global-events 411 | [Page Events]: #page-events 412 | [post_build]: #on_post_build 413 | [post_template]: #on_post_template 414 | [static_templates]: configuration.md#static_templates 415 | [Template Events]: #template-events 416 | -------------------------------------------------------------------------------- /docs/user-guide/styling-your-docs.md: -------------------------------------------------------------------------------- 1 | # Styling your docs 2 | 3 | How to style and theme your documentation. 4 | 5 | --- 6 | 7 | MkDocs includes a couple [built-in themes] as well as various [third party 8 | themes], all of which can easily be customized with [extra CSS or 9 | JavaScript][docs_dir] or overridden from the theme's [custom_dir]. You can also 10 | create your own [custom theme] from the ground up for your documentation. 11 | 12 | To use a theme that is included in MkDocs, simply add this to your 13 | `mkdocs.yml` config file. 14 | 15 | theme: readthedocs 16 | 17 | Replace [`readthedocs`](#readthedocs) with any of the [built-in themes] listed below. 18 | 19 | To create a new custom theme see the [Custom Themes][custom theme] page, or to 20 | more heavily customize an existing theme, see 21 | the [Customizing a Theme][customize] section below. 22 | 23 | ## Built-in themes 24 | 25 | ### mkdocs 26 | 27 | The default theme, which was built as a custom [Bootstrap] theme, supports most 28 | every feature of MkDocs. It only officially supports two levels in the 29 | navigation (see #1107). 30 | 31 | ![mkdocs](../img/mkdocs.png) 32 | 33 | In addition to the default [theme configuration options], the `mkdocs` theme 34 | supports the following options: 35 | 36 | * __`highlightjs`__: Enables highlighting of source code in code blocks using 37 | the [highlight.js] JavaScript library. Default: `True`. 38 | 39 | * __`hljs_style`__: The highlight.js library provides 79 different [styles] 40 | (color variations) for highlighting source code in code blocks. Set this to 41 | the name of the desired style. Default: `github`. 42 | 43 | * __`hljs_languages`__: By default, highlight.js only supports 23 common 44 | languages. List additional languages here to include support for them. 45 | 46 | theme: 47 | name: mkdocs 48 | highlightjs: true 49 | hljs_languages: 50 | - yaml 51 | - rust 52 | 53 | * __`shortcuts`__: Defines keyboard shortcut keys. 54 | 55 | theme: 56 | name: mkdocs 57 | shortcuts: 58 | help: 191 # ? 59 | next: 78 # n 60 | previous: 80 # p 61 | search: 83 # s 62 | 63 | All values much be numeric key codes. It is best to use keys which are 64 | available on all keyboards. You may use to determine 65 | the key code for a given key. 66 | 67 | * __`help`__: Display a help modal which lists the keyboard shortcuts. 68 | Default: `191` (?) 69 | 70 | * __`next`__: Navigate to the "next" page. Default: `78` (n) 71 | 72 | * __`previous`__: Navigate to the "previous" page. Default: `80` (p) 73 | 74 | * __`search`__: Display the search modal. Default: `83` (s) 75 | 76 | [styles]: https://highlightjs.org/static/demo/ 77 | 78 | ### readthedocs 79 | 80 | A clone of the default theme used by the [Read the Docs] service, which offers 81 | the same restricted feature-set as its parent theme. Like its parent theme, only 82 | two levels of navigation are supported. 83 | 84 | ![ReadTheDocs](../img/readthedocs.png) 85 | 86 | In addition to the default [theme configuration options], the `readthedocs` 87 | theme supports the following options: 88 | 89 | * __`highlightjs`__: Enables highlighting of source code in code blocks using 90 | the [highlight.js] JavaScript library. Default: `True`. 91 | 92 | * __`hljs_languages`__: By default, highlight.js only supports 23 common 93 | languages. List additional languages here to include support for them. 94 | 95 | theme: 96 | name: readthedocs 97 | highlightjs: true 98 | hljs_languages: 99 | - yaml 100 | - rust 101 | 102 | ### Third Party Themes 103 | 104 | A list of third party themes can be found in the MkDocs [community wiki]. If you 105 | have created your own, please feel free to add it to the list. 106 | 107 | ## Customizing a Theme 108 | 109 | If you would like to make a few tweaks to an existing theme, there is no need to 110 | create your own theme from scratch. For minor tweaks which only require some CSS 111 | and/or JavaScript, you can use the [docs_dir]. However, for more complex 112 | customizations, including overriding templates, you will need to use the theme 113 | [custom_dir] setting. 114 | 115 | ### Using the docs_dir 116 | 117 | The [extra_css] and [extra_javascript] configuration options can be used to 118 | make tweaks and customizations to existing themes. To use these, you simply 119 | need to include either CSS or JavaScript files within your [documentation 120 | directory]. 121 | 122 | For example, to change the colour of the headers in your documentation, create 123 | a file called `extra.css` and place it next to the documentation Markdown. In 124 | that file add the following CSS. 125 | 126 | ```CSS 127 | h1 { 128 | color: red; 129 | } 130 | ``` 131 | 132 | !!! note 133 | 134 | If you are deploying your documentation with [ReadTheDocs]. You will need 135 | to explicitly list the CSS and JavaScript files you want to include in 136 | your config. To do this, add the following to your mkdocs.yml. 137 | 138 | extra_css: [extra.css] 139 | 140 | After making these changes, they should be visible when you run 141 | `mkdocs serve` - if you already had this running, you should see that the CSS 142 | changes were automatically picked up and the documentation will be updated. 143 | 144 | !!! note 145 | 146 | Any extra CSS or JavaScript files will be added to the generated HTML 147 | document after the page content. If you desire to include a JavaScript 148 | library, you may have better success including the library by using the 149 | theme [custom_dir]. 150 | 151 | ### Using the theme custom_dir 152 | 153 | The theme.[custom_dir] configuration option can be used to point to a directory 154 | of files which override the files in a parent theme. The parent theme would be 155 | the theme defined in the theme.[name] configuration option. Any file in the 156 | `custom_dir` with the same name as a file in the parent theme will replace the 157 | file of the same name in the parent theme. Any additional files in the 158 | `custom_dir` will be added to the parent theme. The contents of the `custom_dir` 159 | should mirror the directory structure of the parent theme. You may include 160 | templates, JavaScript files, CSS files, images, fonts, or any other media 161 | included in a theme. 162 | 163 | !!! Note 164 | 165 | For this to work, the theme `name` setting must be set to a known installed theme. 166 | If the `name` setting is instead set to `null` (or not defined), then there 167 | is no theme to override and the contents of the `custom_dir` must be a 168 | complete, standalone theme. See [Custom Themes][custom theme] for more 169 | information. 170 | 171 | For example, the [mkdocs] theme ([browse source]), contains the following 172 | directory structure (in part): 173 | 174 | ```nohighlight 175 | - css\ 176 | - fonts\ 177 | - img\ 178 | - favicon.ico 179 | - grid.png 180 | - js\ 181 | - 404.html 182 | - base.html 183 | - content.html 184 | - nav-sub.html 185 | - nav.html 186 | - toc.html 187 | ``` 188 | 189 | To override any of the files contained in that theme, create a new directory 190 | next to your `docs_dir`: 191 | 192 | ```bash 193 | mkdir custom_theme 194 | ``` 195 | 196 | And then point your `mkdocs.yml` configuration file at the new directory: 197 | 198 | ```yaml 199 | theme: 200 | name: mkdocs 201 | custom_dir: custom_theme/ 202 | ``` 203 | 204 | To override the 404 error page ("file not found"), add a new template file named 205 | `404.html` to the `custom_theme` directory. For information on what can be 206 | included in a template, review the documentation for building a [custom theme]. 207 | 208 | To override the favicon, you can add a new icon file at 209 | `custom_theme/img/favicon.ico`. 210 | 211 | To include a JavaScript library, copy the library to the `custom_theme/js/` 212 | directory. 213 | 214 | Your directory structure should now look like this: 215 | 216 | ```nohighlight 217 | - docs/ 218 | - index.html 219 | - custom_theme/ 220 | - img/ 221 | - favicon.ico 222 | - js/ 223 | - somelib.js 224 | - 404.html 225 | - config.yml 226 | ``` 227 | 228 | !!! Note 229 | 230 | Any files included in the parent theme (defined in `name`) but not included 231 | in the `custom_dir` will still be utilized. The `custom_dir` will only 232 | override/replace files in the parent theme. If you want to remove files, or 233 | build a theme from scratch, then you should review the documentation for 234 | building a [custom theme]. 235 | 236 | #### Overriding Template Blocks 237 | 238 | The built-in themes implement many of their parts inside template blocks which 239 | can be individually overridden in the `main.html` template. Simply create a 240 | `main.html` template file in your `custom_dir` and define replacement blocks 241 | within that file. Just make sure that the `main.html` extends `base.html`. For 242 | example, to alter the title of the MkDocs theme, your replacement `main.html` 243 | template would contain the following: 244 | 245 | ```django 246 | {% extends "base.html" %} 247 | 248 | {% block title %} 249 | Custom title goes here 250 | {% endblock %} 251 | ``` 252 | 253 | In the above example, the title block defined in your custom `main.html` file 254 | will be used in place of the default title block defined in the parent theme. 255 | You may re-define as many blocks as you desire, as long as those blocks are 256 | defined in the parent. For example, you could replace the Google Analytics 257 | script with one for a different service or replace the search feature with your 258 | own. You will need to consult the parent theme you are using to determine what 259 | blocks are available to override. The MkDocs and ReadTheDocs themes provide the 260 | following blocks: 261 | 262 | * `site_meta`: Contains meta tags in the document head. 263 | * `htmltitle`: Contains the page title in the document head. 264 | * `styles`: Contains the link tags for stylesheets. 265 | * `libs`: Contains the JavaScript libraries (jQuery, etc) included in the page header. 266 | * `scripts`: Contains JavaScript scripts which should execute after a page loads. 267 | * `analytics`: Contains the analytics script. 268 | * `extrahead`: An empty block in the `` to insert custom tags/scripts/etc. 269 | * `site_name`: Contains the site name in the navigation bar. 270 | * `site_nav`: Contains the site navigation in the navigation bar. 271 | * `search_box`: Contains the search box in the navigation bar. 272 | * `next_prev`: Contains the next and previous buttons in the navigation bar. 273 | * `repo`: Contains the repository link in the navigation bar. 274 | * `content`: Contains the page content and table of contents for the page. 275 | * `footer`: Contains the page footer. 276 | 277 | You may need to view the source template files to ensure your modifications will 278 | work with the structure of the site. See [Template Variables] for a list of 279 | variables you can use within your custom blocks. For a more complete 280 | explanation of blocks, consult the [Jinja documentation]. 281 | 282 | #### Combining the custom_dir and Template Blocks 283 | 284 | Adding a JavaScript library to the `custom_dir` will make it available, but 285 | won't include it in the pages generated by MkDocs. Therefore, a link needs to 286 | be added to the library from the HTML. 287 | 288 | Starting the with directory structure above (truncated): 289 | 290 | ```nohighlight 291 | - docs/ 292 | - custom_theme/ 293 | - js/ 294 | - somelib.js 295 | - config.yml 296 | ``` 297 | 298 | A link to the `custom_theme/js/somelib.js` file needs to be added to the 299 | template. As `somelib.js` is a JavaScript library, it would logically go in the 300 | `libs` block. However, a new `libs` block that only includes the new script will 301 | replace the block defined in the parent template and any links to libraries in 302 | the parent template will be removed. To avoid breaking the template, a 303 | [super block] can be used with a call to `super` from within the block: 304 | 305 | ```django 306 | {% extends "base.html" %} 307 | 308 | {% block libs %} 309 | {{ super() }} 310 | 311 | {% endblock %} 312 | ``` 313 | 314 | Note that the [base_url] template variable was used to ensure that the link is 315 | always relative to the current page. 316 | 317 | Now the generated pages will include links to the template provided libraries as 318 | well as the library included in the `custom_dir`. The same would be required for 319 | any additional CSS files included in the `custom_dir`. 320 | 321 | [browse source]: https://github.com/mkdocs/mkdocs/tree/master/mkdocs/themes/mkdocs 322 | [built-in themes]: #built-in-themes 323 | [Bootstrap]: https://getbootstrap.com/ 324 | [theme configuration options]: ./configuration.md#theme 325 | [Read the Docs]: https://readthedocs.org/ 326 | [community wiki]: https://github.com/mkdocs/mkdocs/wiki/MkDocs-Themes 327 | [custom theme]: ./custom-themes.md 328 | [customize]: #customizing-a-theme 329 | [docs_dir]: #using-the-docs_dir 330 | [documentation directory]: ./configuration.md#docs_dir 331 | [extra_css]: ./configuration.md#extra_css 332 | [extra_javascript]: ./configuration.md#extra_javascript 333 | [Jinja documentation]: http://jinja.pocoo.org/docs/dev/templates/#template-inheritance 334 | [mkdocs]: #mkdocs 335 | [ReadTheDocs]: ./deploying-your-docs.md#readthedocs 336 | [Template Variables]: ./custom-themes.md#template-variables 337 | [custom_dir]: ./configuration.md#custom_dir 338 | [name]: ./configuration.md#name 339 | [third party themes]: #third-party-themes 340 | [super block]: http://jinja.pocoo.org/docs/dev/templates/#super-blocks 341 | [base_url]: ./custom-themes.md#base_url 342 | [highlight.js]: https://highlightjs.org/ 343 | -------------------------------------------------------------------------------- /docs/user-guide/writing-your-docs.md: -------------------------------------------------------------------------------- 1 | # Writing your docs 2 | 3 | How to layout and write your Markdown source files. 4 | 5 | --- 6 | 7 | ## File layout 8 | 9 | Your documentation source should be written as regular Markdown files (see 10 | [Writing with Markdown](#writing-with-markdown) below), and placed in the 11 | [documentation directory](configuration.md#docs_dir). By default, this directory 12 | will be named `docs` and will exist at the top level of your project, alongside 13 | the `mkdocs.yml` configuration file. 14 | 15 | The simplest project you can create will look something like this: 16 | 17 | ```no-highlight 18 | mkdocs.yml 19 | docs/ 20 | index.md 21 | ``` 22 | 23 | By convention your project homepage should always be named `index`. Any of the 24 | following extensions may be used for your Markdown source files: `markdown`, 25 | `mdown`, `mkdn`, `mkd`, `md`. All Markdown files included in your documentation 26 | directory will be rendered in the built site regardless of any settings. 27 | 28 | You can also create multi-page documentation, by creating several Markdown 29 | files: 30 | 31 | ```no-highlight 32 | mkdocs.yml 33 | docs/ 34 | index.md 35 | about.md 36 | license.md 37 | ``` 38 | 39 | The file layout you use determines the URLs that are used for the generated 40 | pages. Given the above layout, pages would be generated for the following URLs: 41 | 42 | ```no-highlight 43 | / 44 | /about/ 45 | /license/ 46 | ``` 47 | 48 | You can also include your Markdown files in nested directories if that better 49 | suits your documentation layout. 50 | 51 | ```no-highlight 52 | docs/ 53 | index.md 54 | user-guide/getting-started.md 55 | user-guide/configuration-options.md 56 | license.md 57 | ``` 58 | 59 | Source files inside nested directories will cause pages to be generated with 60 | nested URLs, like so: 61 | 62 | ```no-highlight 63 | / 64 | /user-guide/getting-started/ 65 | /user-guide/configuration-options/ 66 | /license/ 67 | ``` 68 | 69 | ### Index pages 70 | 71 | When a directory is requested, by default, most web servers will return an index 72 | file (usually named `index.html`) contained within that directory if one exists. 73 | For that reason, the homepage in all of the examples above has been named 74 | `index.md`, which MkDocs will render to `index.html` when building the site. 75 | 76 | Many repository hosting sites provide special treatment for README files by 77 | displaying the contents of the README file when browsing the contents of a 78 | directory. Therefore, MkDocs will allow you to name your index pages as 79 | `README.md` instead of `index.md`. In that way, when users are browsing your 80 | source code, the repository host can display the index page of that directory as 81 | it is a README file. However, when MkDocs renders your site, the file will be 82 | renamed to `index.html` so that the server will serve it as a proper index file. 83 | 84 | You should not include both an `index.md` file and a `README.md` file in the 85 | same directory. It is suggested that you chose a convention for your project and 86 | then stick to it. 87 | 88 | ### Configure Pages and Navigation 89 | 90 | The [nav](configuration.md#nav) configuration setting in your `mkdocs.yml` file 91 | defines which pages are included in the global site navigation menu as well as 92 | the structure of that menu. If not provided, the navigation will be 93 | automatically created by discovering all the Markdown files in the 94 | [documentation directory](configuration.md#docs_dir). An automatically created 95 | navigation configuration will always be sorted alphanumerically by file name 96 | (except that index files will always be listed first within a sub-section). You 97 | will need to manually define your navigation configuration if you would like 98 | your navigation menu sorted differently. 99 | 100 | A simple navigation configuration looks like this: 101 | 102 | ```no-highlight 103 | nav: 104 | - 'index.md' 105 | - 'about.md' 106 | ``` 107 | 108 | All paths in the navigation configuration must be relative to the `docs_dir` 109 | configuration option. If that option is set to the default value, `docs`, the 110 | source files for the above configuration would be located at `docs/index.md` and 111 | `docs/about.md`. 112 | 113 | The above example will result in two navigation items being created at the top 114 | level and with their titles inferred from the contents of the file (or the 115 | filename if no title is defined within the file). To define a custom title for 116 | the pages, the title can be added before the filename. 117 | 118 | ```no-highlight 119 | nav: 120 | - Home: 'index.md' 121 | - About: 'about.md' 122 | ``` 123 | 124 | Note that if a title is defined for a page in the navigation, that title will be 125 | used throughout the site for that page and will override any title defined 126 | within the page itself. 127 | 128 | Navigation sub-sections can be created by listing related pages together under a 129 | section title. For example: 130 | 131 | ```no-highlight 132 | nav: 133 | - Home: 'index.md' 134 | - User Guide: 135 | - 'Writing your docs': 'writing-your-docs.md' 136 | - 'Styling your docs': 'styling-your-docs.md' 137 | - About: 138 | - 'License': 'license.md' 139 | - 'Release Notes': 'release-notes.md' 140 | ``` 141 | 142 | With the above configuration we have three top level items: "Home", "User Guide" 143 | and "About." "Home" is a link to the homepage for the site. Under the "User 144 | Guide" section two pages are listed: "Writing your docs" and "Styling your 145 | docs." Under the "About" section two more pages are listed: "License" and 146 | "Release Notes." 147 | 148 | Note that a section cannot have a page assigned to it. Sections are only 149 | containers for child pages and sub-sections. You may nest sections as deeply as 150 | you like. However, be careful that you don't make it too difficult for your 151 | users to navigate through the site navigation by over-complicating the nesting. 152 | While sections may mirror your directly structure, they do not have to. 153 | 154 | Any pages not listed in your navigation configuration will still be rendered and 155 | included with the built site, however, they will not be linked from the global 156 | navigation and will not be included in the `previous` and `next` links. Such 157 | pages will be "hidden" unless linked to directly. 158 | 159 | ## Writing with Markdown 160 | 161 | MkDocs pages must be authored in [Markdown][md], a lightweight markup language 162 | which results in easy-to-read, easy-to-write plain text documents that can be 163 | converted to valid HTML documents in a predictable manner. 164 | 165 | MkDocs uses the [Python-Markdown] library to render Markdown documents to HTML. 166 | Python-Markdown is almost completely compliant with the [reference 167 | implementation][md], although there are a few very minor [differences]. 168 | 169 | In addition to the base Markdown [syntax] which is common across all Markdown 170 | implementations, MkDocs includes support for extending the Markdown syntax with 171 | Python-Markdown [extensions]. See the MkDocs' [markdown_extensions] 172 | configuration setting for details on how to enable extensions. 173 | 174 | MkDocs includes some extensions by default, which are highlighted below. 175 | 176 | [Python-Markdown]: https://python-markdown.github.io/ 177 | [md]: https://daringfireball.net/projects/markdown/ 178 | [differences]: https://python-markdown.github.io/#differences 179 | [syntax]: https://daringfireball.net/projects/markdown/syntax 180 | [extensions]: https://python-markdown.github.io/extensions/ 181 | [markdown_extensions]: configuration.md#markdown_extensions 182 | 183 | ### Internal links 184 | 185 | MkDocs allows you to interlink your documentation by using regular Markdown 186 | [links]. However, there are a few additional benefits to formatting those links 187 | specifically for MkDocs as outlined below. 188 | 189 | [links]: https://daringfireball.net/projects/markdown/syntax#link 190 | 191 | #### Linking to pages 192 | 193 | When linking between pages in the documentation you can simply use the regular 194 | Markdown [linking][links] syntax, including the *relative path* to the Markdown 195 | document you wish to link to. 196 | 197 | ```no-highlight 198 | Please see the [project license](license.md) for further details. 199 | ``` 200 | 201 | When the MkDocs build runs, these Markdown links will automatically be 202 | transformed into an HTML hyperlink to the appropriate HTML page. 203 | 204 | If the target documentation file is in another directory you'll need to make 205 | sure to include any relative directory path in the link. 206 | 207 | ```no-highlight 208 | Please see the [project license](../about/license.md) for further details. 209 | ``` 210 | 211 | The [toc] extension is used by MkDocs to generate an ID for every header in your 212 | Markdown documents. You can use that ID to link to a section within a target 213 | document by using an anchor link. The generated HTML will correctly transform 214 | the path portion of the link, and leave the anchor portion intact. 215 | 216 | ```no-highlight 217 | Please see the [project license](about.md#license) for further details. 218 | ``` 219 | 220 | Note that IDs are created from the text of a header. All text is converted to 221 | lowercase and any disallowed characters, including white-space, are converted to 222 | dashes. Consecutive dashes are then reduced to a single dash. 223 | 224 | There are a few configuration settings provided by the toc extension which you 225 | can set in your `mkdocs.yml` configuration file to alter the default behavior: 226 | 227 | `permalink`: 228 | 229 | : Generate permanent links at the end of each header. Default: `False`. 230 | 231 | When set to True the paragraph symbol (¶ or `¶`) is used as the 232 | link text. When set to a string, the provided string is used as the link 233 | text. For example, to use the hash symbol (`#`) instead, do: 234 | 235 | markdown_extensions: 236 | - toc: 237 | permalink: "#" 238 | 239 | `baselevel`: 240 | 241 | : Base level for headers. Default: `1`. 242 | 243 | This setting allows the header levels to be automatically adjusted to fit 244 | within the hierarchy of your HTML templates. For example, if the Markdown 245 | text for a page should not contain any headers higher than level 2 (`

`), 246 | do: 247 | 248 | markdown_extensions: 249 | - toc: 250 | baselevel: 2 251 | 252 | Then any headers in your document would be increased by 1. For example, the 253 | header `# Header` would be rendered as a level 2 header (`

`) in the HTML 254 | output. 255 | 256 | `separator`: 257 | 258 | : Word separator. Default: `-`. 259 | 260 | Character which replaces white-space in generated IDs. If you prefer 261 | underscores, then do: 262 | 263 | markdown_extensions: 264 | - toc: 265 | separator: "_" 266 | 267 | Note that if you would like to define multiple of the above settings, you must 268 | do so under a single `toc` entry in the `markdown_extensions` configuration 269 | option. 270 | 271 | ```yml 272 | markdown_extensions: 273 | - toc: 274 | permalink: "#" 275 | baselevel: 2 276 | separator: "_" 277 | ``` 278 | 279 | [toc]: https://python-markdown.github.io/extensions/toc/ 280 | 281 | #### Linking to images and media 282 | 283 | As well as the Markdown source files, you can also include other file types in 284 | your documentation, which will be copied across when generating your 285 | documentation site. These might include images and other media. 286 | 287 | For example, if your project documentation needed to include a [GitHub pages 288 | CNAME file] and a PNG formatted screenshot image then your file layout might 289 | look as follows: 290 | 291 | ```no-highlight 292 | mkdocs.yml 293 | docs/ 294 | CNAME 295 | index.md 296 | about.md 297 | license.md 298 | img/ 299 | screenshot.png 300 | ``` 301 | 302 | To include images in your documentation source files, simply use any of the 303 | regular Markdown image syntaxes: 304 | 305 | ```Markdown 306 | Cupcake indexer is a snazzy new project for indexing small cakes. 307 | 308 | ![Screenshot](img/screenshot.png) 309 | 310 | *Above: Cupcake indexer in progress* 311 | ``` 312 | 313 | Your image will now be embedded when you build the documentation, and should 314 | also be previewed if you're working on the documentation with a Markdown editor. 315 | 316 | [GitHub pages CNAME file]: https://help.github.com/articles/using-a-custom-domain-with-github-pages/ 317 | 318 | #### Linking from raw HTML 319 | 320 | Markdown allows document authors to fall back to raw HTML when the Markdown 321 | syntax does not meets the author's needs. MkDocs does not limit Markdown in this 322 | regard. However, as all raw HTML is ignored by the Markdown parser, MkDocs is 323 | not able to validate or convert links contained in raw HTML. When including 324 | internal links within raw HTML, you will need to manually format the link 325 | appropriately for the rendered document. 326 | 327 | ### Meta-Data 328 | 329 | MkDocs includes support for both YAML and MultiMarkdown style meta-data (often 330 | called front-matter). Meta-data consists of a series of keywords and values 331 | defined at the beginning of a Markdown document, which are stripped from the 332 | document prior to it being processing by Python-Markdown. The key/value pairs 333 | are passed by MkDocs to the page template. Therefore, if a theme includes 334 | support, the values of any keys can be displayed on the page or used to control 335 | the page rendering. See your theme's documentation for information about which 336 | keys may be supported, if any. 337 | 338 | In addition to displaying information in a template, MkDocs includes support for 339 | a few predefined meta-data keys which can alter the behavior of MkDocs for that 340 | specific page. The following keys are supported: 341 | 342 | `template`: 343 | 344 | : The template to use with the current page. 345 | 346 | By default, MkDocs uses the `main.html` template of a theme to render 347 | Markdown pages. You can use the `template` meta-data key to define a 348 | different template file for that specific page. The template file must be 349 | available on the path(s) defined in the theme's environment. 350 | 351 | `title`: 352 | 353 | : The "title" to use for the document. 354 | 355 | MkDocs will attempt to determine the title of a document in the following 356 | ways, in order: 357 | 358 | 1. A title defined in the [nav] configuration setting for a document. 359 | 2. A title defined in the `title` meta-data key of a document. 360 | 3. A level 1 Markdown header on the first line of the document body. 361 | 4. The filename of a document. 362 | 363 | Upon finding a title for a page, MkDoc does not continue checking any 364 | additional sources in the above list. 365 | 366 | #### YAML Style Meta-Data 367 | 368 | YAML style meta-data consists of [YAML] key/value pairs wrapped in YAML style 369 | deliminators to mark the start and/or end of the meta-data. The first line of 370 | a document must be `---`. The meta-data ends at the first line containing an 371 | end deliminator (either `---` or `...`). The content between the deliminators is 372 | parsed as [YAML]. 373 | 374 | ```no-highlight 375 | --- 376 | title: My Document 377 | summary: A brief description of my document. 378 | authors: 379 | - Waylan Limberg 380 | - Tom Christie 381 | date: 2018-07-10 382 | some_url: https://example.com 383 | --- 384 | This is the first paragraph of the document. 385 | ``` 386 | 387 | YAML is able to detect data types. Therefore, in the above example, the values 388 | of `title`, `summary` and `some_url` are strings, the value of `authors` is a 389 | list of strings and the value of `date` is a `datetime.date` object. Note that 390 | the YAML keys are case sensitive and MkDocs expects keys to be all lowercase. 391 | The top level of the YAML must be a collection of key/value pairs, which results 392 | in a Python `dict` being returned. If any other type is returned or the YAML 393 | parser encounters an error, then MkDocs does not recognize the section as 394 | meta-data, the page's `meta` attribute will be empty, and the section is not 395 | removed from the document. 396 | 397 | #### MultiMarkdown Style Meta-Data 398 | 399 | MultiMarkdown style meta-data uses a format first introduced by the 400 | [MultiMarkdown] project. The data consists of a series of keywords and values 401 | defined at the beginning of a Markdown document, like this: 402 | 403 | ```no-highlight 404 | Title: My Document 405 | Summary: A brief description of my document. 406 | Authors: Waylan Limberg 407 | Tom Christie 408 | Date: January 23, 2018 409 | blank-value: 410 | some_url: https://example.com 411 | 412 | This is the first paragraph of the document. 413 | ``` 414 | 415 | The keywords are case-insensitive and may consist of letters, numbers, 416 | underscores and dashes and must end with a colon. The values consist of anything 417 | following the colon on the line and may even be blank. 418 | 419 | If a line is indented by 4 or more spaces, that line is assumed to be an 420 | additional line of the value for the previous keyword. A keyword may have as 421 | many lines as desired. All lines are joined into a single string. 422 | 423 | The first blank line ends all meta-data for the document. Therefore, the first 424 | line of a document must not be blank. 425 | 426 | !!! note 427 | 428 | MkDocs does not support YAML style deliminators (`---` or `...`) for 429 | MultiMarkdown style meta-data. In fact, MkDocs relies on the the presence or 430 | absence of the deliminators to determine whether YAML style meta-data or 431 | MultiMarkdown style meta-data is being used. If the deliminators are 432 | detected, but the content between the deliminators is not valid YAML 433 | meta-data, MkDocs does not attempt to parse the content as MultiMarkdown 434 | style meta-data. 435 | 436 | [YAML]: http://yaml.org 437 | [MultiMarkdown]: http://fletcherpenney.net/MultiMarkdown_Syntax_Guide#metadata 438 | [nav]: configuration.md#nav 439 | 440 | ### Tables 441 | 442 | The [tables] extension adds a basic table syntax to Markdown which is popular 443 | across multiple implementations. The syntax is rather simple and is generally 444 | only useful for simple tabular data. 445 | 446 | A simple table looks like this: 447 | 448 | ```no-highlight 449 | First Header | Second Header | Third Header 450 | ------------ | ------------- | ------------ 451 | Content Cell | Content Cell | Content Cell 452 | Content Cell | Content Cell | Content Cell 453 | ``` 454 | 455 | If you wish, you can add a leading and tailing pipe to each line of the table: 456 | 457 | ```no-highlight 458 | | First Header | Second Header | Third Header | 459 | | ------------ | ------------- | ------------ | 460 | | Content Cell | Content Cell | Content Cell | 461 | | Content Cell | Content Cell | Content Cell | 462 | ``` 463 | 464 | Specify alignment for each column by adding colons to separator lines: 465 | 466 | ```no-highlight 467 | First Header | Second Header | Third Header 468 | :----------- |:-------------:| -----------: 469 | Left | Center | Right 470 | Left | Center | Right 471 | ``` 472 | 473 | Note that table cells cannot contain any block level elements and cannot contain 474 | multiple lines of text. They can, however, include inline Markdown as defined in 475 | Markdown's [syntax] rules. 476 | 477 | Additionally, a table must be surrounded by blank lines. There must be a blank 478 | line before and after the table. 479 | 480 | [tables]: https://python-markdown.github.io/extensions/tables/ 481 | 482 | ### Fenced code blocks 483 | 484 | The [fenced code blocks] extension adds an alternate method of defining code 485 | blocks without indentation. 486 | 487 | The first line should contain 3 or more backtick (`` ` ``) characters, and the 488 | last line should contain the same number of backtick characters (`` ` ``): 489 | 490 | ~~~no-highlight 491 | ``` 492 | Fenced code blocks are like Standard 493 | Markdown’s regular code blocks, except that 494 | they’re not indented and instead rely on 495 | start and end fence lines to delimit the 496 | code block. 497 | ``` 498 | ~~~ 499 | 500 | With this approach, the language can optionally be specified on the first line 501 | after the backticks which informs any syntax highlighters of the language used: 502 | 503 | ~~~no-highlight 504 | ```python 505 | def fn(): 506 | pass 507 | ``` 508 | ~~~ 509 | 510 | Note that fenced code blocks can not be indented. Therefore, they cannot be 511 | nested inside list items, blockquotes, etc. 512 | 513 | [fenced code blocks]: https://python-markdown.github.io/extensions/fenced_code_blocks/ 514 | -------------------------------------------------------------------------------- /global.h: -------------------------------------------------------------------------------- 1 | #ifndef GLOBALE_H 2 | #define GLOBALE_H 3 | 4 | #include 5 | 6 | 7 | namespace Global 8 | { 9 | 10 | typedef struct 11 | { 12 | QString ipAdd="192.168.0.100"; 13 | int DB_Read=1; 14 | int DB_Len=100; 15 | byte DB_Buffer[DB_Len];// resize array before using 16 | } st_PLC; 17 | 18 | st_PLC PLC; 19 | 20 | } // namespace Global 21 | 22 | #endif // GLOBALE_H 23 | -------------------------------------------------------------------------------- /images/S71200-DB1 monitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abedGNU/QtSnap7/fa9cedc137408377cfe77457e46d1b332a7612ea/images/S71200-DB1 monitor.png -------------------------------------------------------------------------------- /images/S71200-DB1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abedGNU/QtSnap7/fa9cedc137408377cfe77457e46d1b332a7612ea/images/S71200-DB1.png -------------------------------------------------------------------------------- /images/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abedGNU/QtSnap7/fa9cedc137408377cfe77457e46d1b332a7612ea/images/Thumbs.db -------------------------------------------------------------------------------- /images/Thumbs.db:encryptable: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abedGNU/QtSnap7/fa9cedc137408377cfe77457e46d1b332a7612ea/images/Thumbs.db:encryptable -------------------------------------------------------------------------------- /lib.pri: -------------------------------------------------------------------------------- 1 | # read librarias from the lib folder for linux or windows 2 | LIBS += -L$$PWD/lib/ -lsnap7 3 | 4 | INCLUDEPATH += $$PWD/. 5 | DEPENDPATH += $$PWD/. 6 | -------------------------------------------------------------------------------- /lib/snap7.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abedGNU/QtSnap7/fa9cedc137408377cfe77457e46d1b332a7612ea/lib/snap7.dll -------------------------------------------------------------------------------- /lib/snap7.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abedGNU/QtSnap7/fa9cedc137408377cfe77457e46d1b332a7612ea/lib/snap7.lib -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | QApplication a(argc, argv); 7 | MainWindow w; 8 | w.show(); 9 | 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | 3 | 4 | MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) 5 | { 6 | setupUi(this); 7 | 8 | Italian = new QTranslator(this); 9 | Italian->load(":/translations/translation/translation_it.qm"); 10 | 11 | pbWrite->setText(tr("Write")); 12 | ipLabel->setText(tr("PLC IP address")+settings.PlcIpAddress); 13 | 14 | plcSiemens = new PLC_Siemens(settings.PlcIpAddress,settings.NoDB, settings.BufferLen); 15 | plcSiemens->start(); 16 | 17 | timer= new QTimer(this); 18 | connect(timer, SIGNAL(timeout()), this, SLOT(update())); 19 | timer->start(100); 20 | 21 | } 22 | 23 | void MainWindow::byteCastingtest() 24 | { 25 | // uint8_t pBuff = { 0x11 , 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19 }; 26 | PtestStruct_t pStruct = (PtestStruct_t)plcSiemens->DB_Buffer; 27 | qDebug()<< "Test casting"; 28 | } 29 | 30 | void MainWindow::changeEvent(QEvent *event) 31 | { 32 | if(event->type() == QEvent::LanguageChange) 33 | { 34 | retranslateUi(this); 35 | } 36 | else 37 | { 38 | QMainWindow::changeEvent(event); 39 | } 40 | } 41 | 42 | 43 | void MainWindow::on_pbWrite_clicked() 44 | { 45 | int dbNo, offset; 46 | dbNo=1; 47 | offset=20; 48 | plcSiemens->WriteVal(plcSiemens->eByte,dbNo,offset,(byte)spinBox->value()); 49 | } 50 | 51 | void MainWindow::update() 52 | { 53 | if (plcSiemens->connect() ) 54 | { 55 | QString txt = "counter 0: " + QString::number( plcSiemens->getUInt32(0)) + "\n\n"; 56 | txt = txt + "counterByte 4: "+ QString::number( plcSiemens->DB_Buffer[4]) + "\n\n"; 57 | txt = txt + "cInt 6: " + QString::number( plcSiemens->getInt16(plcSiemens->DB_Buffer,6 )) + "\n\n"; 58 | txt = txt + "cWord 8: " + QString::number( plcSiemens->getUInt16(plcSiemens->DB_Buffer,8 )) + "\n\n"; 59 | txt = txt + "cDword 10: " + QString::number( plcSiemens->getUInt32(plcSiemens->DB_Buffer,10 )) + "\n\n"; 60 | txt = txt + "cReal 14: " + QString::number( plcSiemens->getReal(plcSiemens->DB_Buffer,14 )) + "\n\n"; 61 | 62 | for(int i=18;i<30;i++) 63 | { 64 | txt = txt + "Byte "+ QString::number(i) +" : " + QString::number( plcSiemens->DB_Buffer[i]) + "\n"; 65 | } 66 | label->setText(txt ); 67 | } 68 | } 69 | 70 | 71 | 72 | void MainWindow::on_pbTestCasting_clicked() 73 | { 74 | byteCastingtest(); 75 | } 76 | 77 | void MainWindow::on_actionEnglish_triggered() 78 | { 79 | qApp->removeTranslator(Italian); 80 | lblLanguage->setText(tr("English")); 81 | } 82 | 83 | void MainWindow::on_actionItalian_triggered() 84 | { 85 | qApp->installTranslator(Italian); 86 | lblLanguage->setText(tr("Italian")); 87 | } 88 | -------------------------------------------------------------------------------- /mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "ui_mainwindow.h" 10 | #include "snap7.h" 11 | #include "plc_siemens.h" 12 | 13 | #include "settings.h" 14 | 15 | class MainWindow : public QMainWindow, private Ui::MainWindow 16 | { 17 | Q_OBJECT 18 | 19 | public: 20 | explicit MainWindow(QWidget *parent = 0); 21 | 22 | Settings settings; 23 | 24 | PLC_Siemens *plcSiemens; 25 | 26 | QTimer *timer ; 27 | 28 | void byteCastingtest(); 29 | 30 | #pragma pack(push, 1) 31 | typedef struct 32 | { 33 | int32_t counterDint; 34 | uint8_t counterByte; 35 | int16_t cInt; 36 | uint16_t cWord; 37 | uint32_t cDWord; 38 | float_t cReal; 39 | uint8_t cByte18; 40 | uint8_t cByte19; 41 | uint8_t cByte20; 42 | uint8_t cByte21; 43 | uint8_t cByte22; 44 | } testStruct_t, *PtestStruct_t; 45 | #pragma pack(pop) 46 | 47 | private: 48 | QTranslator *Italian; 49 | 50 | protected: 51 | //void closeEvent(QCloseEvent *event); 52 | void changeEvent(QEvent *event); 53 | 54 | private slots: 55 | void on_pbWrite_clicked(); 56 | 57 | void update(); 58 | 59 | void on_pbTestCasting_clicked(); 60 | void on_actionEnglish_triggered(); 61 | void on_actionItalian_triggered(); 62 | }; 63 | 64 | #endif // MAINWINDOW_H 65 | -------------------------------------------------------------------------------- /mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 656 10 | 625 11 | 12 | 13 | 14 | MainWindow 15 | 16 | 17 | 18 | 19 | 20 | 20 21 | 130 22 | 321 23 | 351 24 | 25 | 26 | 27 | PLC data 28 | 29 | 30 | 31 | 32 | 33 | 20 34 | 60 35 | 131 36 | 41 37 | 38 | 39 | 40 | Write 41 | 42 | 43 | 44 | 45 | 46 | 170 47 | 60 48 | 91 49 | 41 50 | 51 | 52 | 53 | 54 | 55 | 56 | 500 57 | 80 58 | 131 59 | 41 60 | 61 | 62 | 63 | TestCasting 64 | 65 | 66 | 67 | 68 | 69 | 40 70 | 10 71 | 301 72 | 31 73 | 74 | 75 | 76 | Ip address 77 | 78 | 79 | 80 | 81 | 82 | 440 83 | 10 84 | 131 85 | 41 86 | 87 | 88 | 89 | TextLabel 90 | 91 | 92 | 93 | 94 | 95 | 96 | 0 97 | 0 98 | 656 99 | 22 100 | 101 | 102 | 103 | 104 | Language 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | TopToolBarArea 114 | 115 | 116 | false 117 | 118 | 119 | 120 | 121 | 122 | English 123 | 124 | 125 | 126 | 127 | Italian 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /plc_siemens.cpp: -------------------------------------------------------------------------------- 1 | #include "plc_siemens.h" 2 | 3 | PLC_Siemens::PLC_Siemens(QString ipAddress) 4 | { 5 | MyS7Client = new TS7Client(); 6 | this->ipAddress = ipAddress; 7 | connect(); 8 | } 9 | 10 | PLC_Siemens::PLC_Siemens(QString ipAddress, int DB_No, int DB_Length) 11 | { 12 | MyS7Client = new TS7Client(); 13 | this->ipAddress = ipAddress; 14 | this->DB_No= DB_No; 15 | this->DB_Length = DB_Length; 16 | connect(); 17 | } 18 | 19 | bool PLC_Siemens::connect() 20 | { 21 | if ( !MyS7Client->Connected() ) 22 | { 23 | return MyS7Client->ConnectTo(ipAddress.toStdString().c_str() ,0,0); 24 | } 25 | else { 26 | return MyS7Client->Connected(); 27 | } 28 | } 29 | 30 | void PLC_Siemens::ReadCycle() 31 | { 32 | int res; 33 | res = MyS7Client->DBRead(1, 0, 30, &DB_Buffer); 34 | if (res!=0) 35 | { 36 | qDebug()<< "Error read from DB:" << "1 "<Connected()) 45 | { 46 | if (typ == eByte ) 47 | { 48 | int res = MyS7Client->DBWrite(dbNum, offset,1,&val); 49 | qDebug()<< "Write to DB" << dbNum <<".DBB"< 6 | #include 7 | #include 8 | #include 9 | 10 | class PLC_Siemens : public QThread 11 | { 12 | 13 | 14 | typedef float *pfloat; 15 | 16 | public: 17 | enum dataType {eBit, eByte, eInt, eDInt, eWord, eDowrd, eReal}; 18 | PLC_Siemens(QString ipAddress); 19 | PLC_Siemens(QString ipAddress, int DB_No, int DB_Length); 20 | // 21 | bool connect(); 22 | void ReadCycle(); 23 | bool WriteVal( dataType typ, int dbNum, int offset, int val); 24 | // 25 | QMutex mutex; 26 | 27 | // Helper functions 28 | uint getUInt16(int Pos); 29 | uint getUInt16(byte* Buffer, int Pos); 30 | 31 | int getInt16(int Pos); 32 | int getInt16(byte* Buffer, int Pos); 33 | 34 | int getUInt32( int Pos); 35 | uint getUInt32(byte* Buffer, int Pos); 36 | 37 | int getInt32(int Pos); 38 | int getInt32(byte* Buffer, int Pos); 39 | 40 | double getReal(int Pos); 41 | double getReal(byte* Buffer, int Pos); 42 | // 43 | QString ipAddress; 44 | int DB_No=1; 45 | int DB_Length=20; 46 | 47 | TS7Client *MyS7Client; 48 | byte DB_Buffer[200]; 49 | 50 | protected: 51 | void run(); 52 | private: 53 | int old_value; 54 | }; 55 | 56 | #endif // PLC_SIEMENS_H 57 | -------------------------------------------------------------------------------- /resources.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | images/S71200-DB1.png 4 | 5 | 6 | translation/translation_it.qm 7 | 8 | 9 | -------------------------------------------------------------------------------- /settings.cpp: -------------------------------------------------------------------------------- 1 | #include "settings.h" 2 | 3 | Settings::Settings() 4 | { 5 | QFile settFile(settingsFileName); 6 | int res =-1; 7 | /* If settings file doesn't exist in the default directory 8 | * create new one with default value Or select one 9 | **/ 10 | settings = new QSettings(settingsFileName, QSettings::IniFormat); 11 | if (!settFile.exists()) 12 | { 13 | createDefaultSettings(); 14 | qDebug() << "Creating default setting in: " << "done " << res; 15 | } 16 | else 17 | { 18 | //choose a file from dialog windows?? 19 | } 20 | 21 | /* Load settings from file 22 | **/ 23 | res=loadSettings(); 24 | qDebug() << "Loading setting from: " << "done " << res; 25 | } 26 | 27 | int Settings::loadSettings() 28 | { 29 | settings->beginGroup("PLC"); 30 | PlcIpAddress = settings->value("PlcAddress").toString(); 31 | NoDB = settings->value("DBNumber").toInt(); 32 | BufferLen = settings->value("Bufferlength").toInt(); 33 | settings->endGroup(); 34 | return 0; 35 | } 36 | 37 | int Settings::saveSettings() 38 | { 39 | settings->beginGroup("PLC"); 40 | settings->setValue("PlcAddress", PlcIpAddress); 41 | settings->setValue("DBNumber",NoDB ); 42 | settings->setValue("Bufferlength", BufferLen); 43 | settings->endGroup(); 44 | return 0; 45 | } 46 | 47 | int Settings::createDefaultSettings() 48 | { 49 | settings->beginGroup("PLC"); 50 | settings->setValue("PlcAddress", PlcIpAddressDef); 51 | settings->setValue("DBNumber",NoDBdef); 52 | settings->setValue("Bufferlength", BufferLendef); 53 | settings->endGroup(); 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /settings.h: -------------------------------------------------------------------------------- 1 | #ifndef SETTINGS_H 2 | #define SETTINGS_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class Settings 10 | { 11 | public: 12 | Settings(); 13 | QSettings *settings; 14 | int loadSettings(); 15 | int saveSettings(); 16 | int createDefaultSettings(); 17 | 18 | QString PlcIpAddress; 19 | int NoDB; 20 | int BufferLen; 21 | // 22 | 23 | private: 24 | QString PlcIpAddressDef="192.168.0.100"; 25 | int NoDBdef=1; 26 | int BufferLendef=20; 27 | 28 | QString settingsFileName = "settings.ini"; 29 | }; 30 | 31 | #endif // SETTINGS_H 32 | -------------------------------------------------------------------------------- /snap7.cpp: -------------------------------------------------------------------------------- 1 | /*=============================================================================| 2 | | PROJECT SNAP7 1.4.0 | 3 | |==============================================================================| 4 | | Copyright (C) 2013, 2014 Davide Nardella | 5 | | All rights reserved. | 6 | |==============================================================================| 7 | | SNAP7 is free software: you can redistribute it and/or modify | 8 | | it under the terms of the Lesser GNU General Public License as published by | 9 | | the Free Software Foundation, either version 3 of the License, or | 10 | | (at your option) any later version. | 11 | | | 12 | | It means that you can distribute your commercial software linked with | 13 | | SNAP7 without the requirement to distribute the source code of your | 14 | | application and without the requirement that your application be itself | 15 | | distributed under LGPL. | 16 | | | 17 | | SNAP7 is distributed in the hope that it will be useful, | 18 | | but WITHOUT ANY WARRANTY; without even the implied warranty of | 19 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 20 | | Lesser GNU General Public License for more details. | 21 | | | 22 | | You should have received a copy of the GNU General Public License and a | 23 | | copy of Lesser GNU General Public License along with Snap7. | 24 | | If not, see http://www.gnu.org/licenses/ | 25 | |==============================================================================| 26 | | | 27 | | C++ Snap 7 classes Implementation | 28 | | | 29 | |=============================================================================*/ 30 | 31 | #include "snap7.h" 32 | 33 | //============================================================================== 34 | // CLIENT 35 | //============================================================================== 36 | TS7Client::TS7Client() 37 | { 38 | Client=Cli_Create(); 39 | } 40 | //--------------------------------------------------------------------------- 41 | TS7Client::~TS7Client() 42 | { 43 | Cli_Destroy(&Client); 44 | } 45 | //--------------------------------------------------------------------------- 46 | int TS7Client::Connect() 47 | { 48 | return Cli_Connect(Client); 49 | } 50 | //--------------------------------------------------------------------------- 51 | int TS7Client::ConnectTo(const char *RemAddress, int Rack, int Slot) 52 | { 53 | return Cli_ConnectTo(Client, RemAddress, Rack, Slot); 54 | } 55 | //--------------------------------------------------------------------------- 56 | int TS7Client::SetConnectionParams(const char *RemAddress, word LocalTSAP, word RemoteTSAP) 57 | { 58 | return Cli_SetConnectionParams(Client, RemAddress, LocalTSAP, RemoteTSAP); 59 | } 60 | //--------------------------------------------------------------------------- 61 | int TS7Client::SetConnectionType(word ConnectionType) 62 | { 63 | return Cli_SetConnectionType(Client, ConnectionType); 64 | } 65 | //--------------------------------------------------------------------------- 66 | int TS7Client::Disconnect() 67 | { 68 | return Cli_Disconnect(Client); 69 | } 70 | //--------------------------------------------------------------------------- 71 | int TS7Client::GetParam(int ParamNumber, void *pValue) 72 | { 73 | return Cli_GetParam(Client, ParamNumber, pValue); 74 | } 75 | //--------------------------------------------------------------------------- 76 | int TS7Client::SetParam(int ParamNumber, void *pValue) 77 | { 78 | return Cli_SetParam(Client, ParamNumber, pValue); 79 | } 80 | //--------------------------------------------------------------------------- 81 | int TS7Client::ReadArea(int Area, int DBNumber, int Start, int Amount, int WordLen, void *pUsrData) 82 | { 83 | return Cli_ReadArea(Client, Area, DBNumber, Start, Amount, WordLen, pUsrData); 84 | } 85 | //--------------------------------------------------------------------------- 86 | int TS7Client::WriteArea(int Area, int DBNumber, int Start, int Amount, int WordLen, void *pUsrData) 87 | { 88 | return Cli_WriteArea(Client, Area, DBNumber, Start, Amount, WordLen, pUsrData); 89 | } 90 | //--------------------------------------------------------------------------- 91 | int TS7Client::ReadMultiVars(PS7DataItem Item, int ItemsCount) 92 | { 93 | return Cli_ReadMultiVars(Client, Item, ItemsCount); 94 | } 95 | //--------------------------------------------------------------------------- 96 | int TS7Client::WriteMultiVars(PS7DataItem Item, int ItemsCount) 97 | { 98 | return Cli_WriteMultiVars(Client, Item, ItemsCount); 99 | } 100 | //--------------------------------------------------------------------------- 101 | int TS7Client::DBRead(int DBNumber, int Start, int Size, void *pUsrData) 102 | { 103 | return Cli_DBRead(Client, DBNumber, Start, Size, pUsrData); 104 | } 105 | //--------------------------------------------------------------------------- 106 | int TS7Client::DBWrite(int DBNumber, int Start, int Size, void *pUsrData) 107 | { 108 | return Cli_DBWrite(Client, DBNumber, Start, Size, pUsrData); 109 | } 110 | //--------------------------------------------------------------------------- 111 | int TS7Client::MBRead(int Start, int Size, void *pUsrData) 112 | { 113 | return Cli_MBRead(Client, Start, Size, pUsrData); 114 | } 115 | //--------------------------------------------------------------------------- 116 | int TS7Client::MBWrite(int Start, int Size, void *pUsrData) 117 | { 118 | return Cli_MBWrite(Client, Start, Size, pUsrData); 119 | } 120 | //--------------------------------------------------------------------------- 121 | int TS7Client::EBRead(int Start, int Size, void *pUsrData) 122 | { 123 | return Cli_EBRead(Client, Start, Size, pUsrData); 124 | } 125 | //--------------------------------------------------------------------------- 126 | int TS7Client::EBWrite(int Start, int Size, void *pUsrData) 127 | { 128 | return Cli_EBWrite(Client, Start, Size, pUsrData); 129 | } 130 | //--------------------------------------------------------------------------- 131 | int TS7Client::ABRead(int Start, int Size, void *pUsrData) 132 | { 133 | return Cli_ABRead(Client, Start, Size, pUsrData); 134 | } 135 | //--------------------------------------------------------------------------- 136 | int TS7Client::ABWrite(int Start, int Size, void *pUsrData) 137 | { 138 | return Cli_ABWrite(Client, Start, Size, pUsrData); 139 | } 140 | //--------------------------------------------------------------------------- 141 | int TS7Client::TMRead(int Start, int Amount, void *pUsrData) 142 | { 143 | return Cli_TMRead(Client, Start, Amount, pUsrData); 144 | } 145 | //--------------------------------------------------------------------------- 146 | int TS7Client::TMWrite(int Start, int Amount, void *pUsrData) 147 | { 148 | return Cli_TMWrite(Client, Start, Amount, pUsrData); 149 | } 150 | //--------------------------------------------------------------------------- 151 | int TS7Client::CTRead(int Start, int Amount, void *pUsrData) 152 | { 153 | return Cli_CTRead(Client, Start, Amount, pUsrData); 154 | } 155 | //--------------------------------------------------------------------------- 156 | int TS7Client::CTWrite(int Start, int Amount, void *pUsrData) 157 | { 158 | return Cli_CTWrite(Client, Start, Amount, pUsrData); 159 | } 160 | //--------------------------------------------------------------------------- 161 | int TS7Client::ListBlocks(PS7BlocksList pUsrData) 162 | { 163 | return Cli_ListBlocks(Client, pUsrData); 164 | } 165 | //--------------------------------------------------------------------------- 166 | int TS7Client::GetAgBlockInfo(int BlockType, int BlockNum, PS7BlockInfo pUsrData) 167 | { 168 | return Cli_GetAgBlockInfo(Client, BlockType, BlockNum, pUsrData); 169 | } 170 | //--------------------------------------------------------------------------- 171 | int TS7Client::GetPgBlockInfo(void *pBlock, PS7BlockInfo pUsrData, int Size) 172 | { 173 | return Cli_GetPgBlockInfo(Client, pBlock, pUsrData, Size); 174 | } 175 | //--------------------------------------------------------------------------- 176 | int TS7Client::ListBlocksOfType(int BlockType, TS7BlocksOfType *pUsrData, int *ItemsCount) 177 | { 178 | return Cli_ListBlocksOfType(Client, BlockType, pUsrData, ItemsCount); 179 | } 180 | //--------------------------------------------------------------------------- 181 | int TS7Client::Upload(int BlockType, int BlockNum, void *pUsrData, int *Size) 182 | { 183 | return Cli_Upload(Client, BlockType, BlockNum, pUsrData, Size); 184 | } 185 | //--------------------------------------------------------------------------- 186 | int TS7Client::FullUpload(int BlockType, int BlockNum, void *pUsrData, int *Size) 187 | { 188 | return Cli_FullUpload(Client, BlockType, BlockNum, pUsrData, Size); 189 | } 190 | //--------------------------------------------------------------------------- 191 | int TS7Client::Download(int BlockNum, void *pUsrData, int Size) 192 | { 193 | return Cli_Download(Client, BlockNum, pUsrData, Size); 194 | } 195 | //--------------------------------------------------------------------------- 196 | int TS7Client::Delete(int BlockType, int BlockNum) 197 | { 198 | return Cli_Delete(Client, BlockType, BlockNum); 199 | } 200 | //--------------------------------------------------------------------------- 201 | int TS7Client::DBGet(int DBNumber, void *pUsrData, int *Size) 202 | { 203 | return Cli_DBGet(Client, DBNumber, pUsrData, Size); 204 | } 205 | //--------------------------------------------------------------------------- 206 | int TS7Client::DBFill(int DBNumber, int FillChar) 207 | { 208 | return Cli_DBFill(Client, DBNumber, FillChar); 209 | } 210 | //--------------------------------------------------------------------------- 211 | int TS7Client::GetPlcDateTime(tm *DateTime) 212 | { 213 | return Cli_GetPlcDateTime(Client, DateTime); 214 | } 215 | //--------------------------------------------------------------------------- 216 | int TS7Client::SetPlcDateTime(tm *DateTime) 217 | { 218 | return Cli_SetPlcDateTime(Client, DateTime); 219 | } 220 | //--------------------------------------------------------------------------- 221 | int TS7Client::SetPlcSystemDateTime() 222 | { 223 | return Cli_SetPlcSystemDateTime(Client); 224 | } 225 | //--------------------------------------------------------------------------- 226 | int TS7Client::GetOrderCode(PS7OrderCode pUsrData) 227 | { 228 | return Cli_GetOrderCode(Client, pUsrData); 229 | } 230 | //--------------------------------------------------------------------------- 231 | int TS7Client::GetCpuInfo(PS7CpuInfo pUsrData) 232 | { 233 | return Cli_GetCpuInfo(Client, pUsrData); 234 | } 235 | //--------------------------------------------------------------------------- 236 | int TS7Client::GetCpInfo(PS7CpInfo pUsrData) 237 | { 238 | return Cli_GetCpInfo(Client, pUsrData); 239 | } 240 | //--------------------------------------------------------------------------- 241 | int TS7Client::ReadSZL(int ID, int Index, PS7SZL pUsrData, int *Size) 242 | { 243 | return Cli_ReadSZL(Client, ID, Index, pUsrData, Size); 244 | } 245 | //--------------------------------------------------------------------------- 246 | int TS7Client::ReadSZLList(PS7SZLList pUsrData, int *ItemsCount) 247 | { 248 | return Cli_ReadSZLList(Client, pUsrData, ItemsCount); 249 | } 250 | //--------------------------------------------------------------------------- 251 | int TS7Client::PlcHotStart() 252 | { 253 | return Cli_PlcHotStart(Client); 254 | } 255 | //--------------------------------------------------------------------------- 256 | int TS7Client::PlcColdStart() 257 | { 258 | return Cli_PlcColdStart(Client); 259 | } 260 | //--------------------------------------------------------------------------- 261 | int TS7Client::PlcStop() 262 | { 263 | return Cli_PlcStop(Client); 264 | } 265 | //--------------------------------------------------------------------------- 266 | int TS7Client::CopyRamToRom(int Timeout) 267 | { 268 | return Cli_CopyRamToRom(Client, Timeout); 269 | } 270 | //--------------------------------------------------------------------------- 271 | int TS7Client::Compress(int Timeout) 272 | { 273 | return Cli_Compress(Client, Timeout); 274 | } 275 | //--------------------------------------------------------------------------- 276 | int TS7Client::GetProtection(PS7Protection pUsrData) 277 | { 278 | return Cli_GetProtection(Client, pUsrData); 279 | } 280 | //--------------------------------------------------------------------------- 281 | int TS7Client::SetSessionPassword(char *Password) 282 | { 283 | return Cli_SetSessionPassword(Client, Password); 284 | } 285 | //--------------------------------------------------------------------------- 286 | int TS7Client::ClearSessionPassword() 287 | { 288 | return Cli_ClearSessionPassword(Client); 289 | } 290 | //--------------------------------------------------------------------------- 291 | int TS7Client::ExecTime() 292 | { 293 | int Time; 294 | int Result = Cli_GetExecTime(Client, &Time); 295 | if (Result==0) 296 | return Time; 297 | else 298 | return Result; 299 | } 300 | //--------------------------------------------------------------------------- 301 | int TS7Client::LastError() 302 | { 303 | int LastError; 304 | int Result =Cli_GetLastError(Client, &LastError); 305 | if (Result==0) 306 | return LastError; 307 | else 308 | return Result; 309 | } 310 | //--------------------------------------------------------------------------- 311 | int TS7Client::PDULength() 312 | { 313 | int Requested, Negotiated; 314 | if (Cli_GetPduLength(Client, &Requested, &Negotiated)==0) 315 | return Negotiated; 316 | else 317 | return 0; 318 | } 319 | //--------------------------------------------------------------------------- 320 | int TS7Client::PDURequested() 321 | { 322 | int Requested, Negotiated; 323 | if (Cli_GetPduLength(Client, &Requested, &Negotiated)==0) 324 | return Requested; 325 | else 326 | return 0; 327 | } 328 | //--------------------------------------------------------------------------- 329 | int TS7Client::PlcStatus() 330 | { 331 | int Status; 332 | int Result = Cli_GetPlcStatus(Client, &Status); 333 | if (Result==0) 334 | return Status; 335 | else 336 | return Result; 337 | } 338 | //--------------------------------------------------------------------------- 339 | bool TS7Client::Connected() 340 | { 341 | int ClientStatus; 342 | if (Cli_GetConnected(Client ,&ClientStatus)==0) 343 | return ClientStatus!=0; 344 | else 345 | return false; 346 | } 347 | //--------------------------------------------------------------------------- 348 | int TS7Client::SetAsCallback(pfn_CliCompletion pCompletion, void *usrPtr) 349 | { 350 | return Cli_SetAsCallback(Client, pCompletion, usrPtr); 351 | } 352 | //--------------------------------------------------------------------------- 353 | bool TS7Client::CheckAsCompletion(int *opResult) 354 | { 355 | return Cli_CheckAsCompletion(Client ,opResult)==JobComplete; 356 | } 357 | //--------------------------------------------------------------------------- 358 | int TS7Client::WaitAsCompletion(longword Timeout) 359 | { 360 | return Cli_WaitAsCompletion(Client, Timeout); 361 | } 362 | //--------------------------------------------------------------------------- 363 | int TS7Client::AsReadArea(int Area, int DBNumber, int Start, int Amount, int WordLen, void *pUsrData) 364 | { 365 | return Cli_AsReadArea(Client, Area, DBNumber, Start, Amount, WordLen, pUsrData); 366 | } 367 | //--------------------------------------------------------------------------- 368 | int TS7Client::AsWriteArea(int Area, int DBNumber, int Start, int Amount, int WordLen, void *pUsrData) 369 | { 370 | return Cli_AsWriteArea(Client, Area, DBNumber, Start, Amount, WordLen, pUsrData); 371 | } 372 | //--------------------------------------------------------------------------- 373 | int TS7Client::AsListBlocksOfType(int BlockType, PS7BlocksOfType pUsrData, int *ItemsCount) 374 | { 375 | return Cli_AsListBlocksOfType(Client, BlockType, pUsrData, ItemsCount); 376 | } 377 | //--------------------------------------------------------------------------- 378 | int TS7Client::AsReadSZL(int ID, int Index, PS7SZL pUsrData, int *Size) 379 | { 380 | return Cli_AsReadSZL(Client, ID, Index, pUsrData, Size); 381 | } 382 | //--------------------------------------------------------------------------- 383 | int TS7Client::AsReadSZLList(PS7SZLList pUsrData, int *ItemsCount) 384 | { 385 | return Cli_AsReadSZLList(Client, pUsrData, ItemsCount); 386 | } 387 | //--------------------------------------------------------------------------- 388 | int TS7Client::AsUpload(int BlockType, int BlockNum, void *pUsrData, int *Size) 389 | { 390 | return Cli_AsUpload(Client, BlockType, BlockNum, pUsrData, Size); 391 | } 392 | //--------------------------------------------------------------------------- 393 | int TS7Client::AsFullUpload(int BlockType, int BlockNum, void *pUsrData, int *Size) 394 | { 395 | return Cli_AsFullUpload(Client, BlockType, BlockNum, pUsrData, Size); 396 | } 397 | //--------------------------------------------------------------------------- 398 | int TS7Client::AsDownload(int BlockNum, void *pUsrData, int Size) 399 | { 400 | return Cli_AsDownload(Client, BlockNum, pUsrData, Size); 401 | } 402 | //--------------------------------------------------------------------------- 403 | int TS7Client::AsCopyRamToRom(int Timeout) 404 | { 405 | return Cli_AsCopyRamToRom(Client, Timeout); 406 | } 407 | //--------------------------------------------------------------------------- 408 | int TS7Client::AsCompress(int Timeout) 409 | { 410 | return Cli_AsCompress(Client, Timeout); 411 | } 412 | //--------------------------------------------------------------------------- 413 | int TS7Client::AsDBRead(int DBNumber, int Start, int Size, void *pUsrData) 414 | { 415 | return Cli_AsDBRead(Client, DBNumber, Start, Size, pUsrData); 416 | } 417 | //--------------------------------------------------------------------------- 418 | int TS7Client::AsDBWrite(int DBNumber, int Start, int Size, void *pUsrData) 419 | { 420 | return Cli_AsDBWrite(Client, DBNumber, Start, Size, pUsrData); 421 | } 422 | //--------------------------------------------------------------------------- 423 | int TS7Client::AsMBRead(int Start, int Size, void *pUsrData) 424 | { 425 | return Cli_AsMBRead(Client, Start, Size, pUsrData); 426 | } 427 | //--------------------------------------------------------------------------- 428 | int TS7Client::AsMBWrite(int Start, int Size, void *pUsrData) 429 | { 430 | return Cli_AsMBWrite(Client, Start, Size, pUsrData); 431 | } 432 | //--------------------------------------------------------------------------- 433 | int TS7Client::AsEBRead(int Start, int Size, void *pUsrData) 434 | { 435 | return Cli_AsEBRead(Client, Start, Size, pUsrData); 436 | } 437 | //--------------------------------------------------------------------------- 438 | int TS7Client::AsEBWrite(int Start, int Size, void *pUsrData) 439 | { 440 | return Cli_AsEBWrite(Client, Start, Size, pUsrData); 441 | } 442 | //--------------------------------------------------------------------------- 443 | int TS7Client::AsABRead(int Start, int Size, void *pUsrData) 444 | { 445 | return Cli_AsABRead(Client, Start, Size, pUsrData); 446 | } 447 | //--------------------------------------------------------------------------- 448 | int TS7Client::AsABWrite(int Start, int Size, void *pUsrData) 449 | { 450 | return Cli_AsABWrite(Client, Start, Size, pUsrData); 451 | } 452 | //--------------------------------------------------------------------------- 453 | int TS7Client::AsTMRead(int Start, int Amount, void *pUsrData) 454 | { 455 | return Cli_AsTMRead(Client, Start, Amount, pUsrData); 456 | } 457 | //--------------------------------------------------------------------------- 458 | int TS7Client::AsTMWrite(int Start, int Amount, void *pUsrData) 459 | { 460 | return Cli_AsTMWrite(Client, Start, Amount, pUsrData); 461 | } 462 | //--------------------------------------------------------------------------- 463 | int TS7Client::AsCTRead(int Start, int Amount, void *pUsrData) 464 | { 465 | return Cli_AsCTRead(Client, Start, Amount, pUsrData); 466 | } 467 | //--------------------------------------------------------------------------- 468 | int TS7Client::AsCTWrite(int Start, int Amount, void *pUsrData) 469 | { 470 | return Cli_AsCTWrite(Client, Start, Amount, pUsrData); 471 | } 472 | //--------------------------------------------------------------------------- 473 | int TS7Client::AsDBGet(int DBNumber, void *pUsrData, int *Size) 474 | { 475 | return Cli_AsDBGet(Client, DBNumber, pUsrData, Size); 476 | } 477 | //--------------------------------------------------------------------------- 478 | int TS7Client::AsDBFill(int DBNumber, int FillChar) 479 | { 480 | return Cli_AsDBFill(Client, DBNumber, FillChar); 481 | } 482 | //============================================================================== 483 | // SERVER 484 | //============================================================================== 485 | TS7Server::TS7Server() 486 | { 487 | Server=Srv_Create(); 488 | } 489 | //--------------------------------------------------------------------------- 490 | TS7Server::~TS7Server() 491 | { 492 | Srv_Destroy(&Server); 493 | } 494 | //--------------------------------------------------------------------------- 495 | int TS7Server::Start() 496 | { 497 | return Srv_Start(Server); 498 | } 499 | //--------------------------------------------------------------------------- 500 | int TS7Server::StartTo(const char *Address) 501 | { 502 | return Srv_StartTo(Server, Address); 503 | } 504 | //--------------------------------------------------------------------------- 505 | int TS7Server::Stop() 506 | { 507 | return Srv_Stop(Server); 508 | } 509 | //--------------------------------------------------------------------------- 510 | int TS7Server::GetParam(int ParamNumber, void *pValue) 511 | { 512 | return Srv_GetParam(Server, ParamNumber, pValue); 513 | } 514 | //--------------------------------------------------------------------------- 515 | int TS7Server::SetParam(int ParamNumber, void *pValue) 516 | { 517 | return Srv_SetParam(Server, ParamNumber, pValue); 518 | } 519 | //--------------------------------------------------------------------------- 520 | int TS7Server::SetEventsCallback(pfn_SrvCallBack PCallBack, void *UsrPtr) 521 | { 522 | return Srv_SetEventsCallback(Server, PCallBack, UsrPtr); 523 | } 524 | //--------------------------------------------------------------------------- 525 | int TS7Server::SetReadEventsCallback(pfn_SrvCallBack PCallBack, void *UsrPtr) 526 | { 527 | return Srv_SetReadEventsCallback(Server, PCallBack, UsrPtr); 528 | } 529 | //--------------------------------------------------------------------------- 530 | int TS7Server::SetRWAreaCallback(pfn_RWAreaCallBack PCallBack, void *UsrPtr) 531 | { 532 | return Srv_SetRWAreaCallback(Server, PCallBack, UsrPtr); 533 | } 534 | //--------------------------------------------------------------------------- 535 | bool TS7Server::PickEvent(TSrvEvent *pEvent) 536 | { 537 | int EvtReady; 538 | if (Srv_PickEvent(Server, pEvent, &EvtReady)==0) 539 | return EvtReady!=0; 540 | else 541 | return false; 542 | } 543 | //--------------------------------------------------------------------------- 544 | void TS7Server::ClearEvents() 545 | { 546 | Srv_ClearEvents(Server); 547 | } 548 | //--------------------------------------------------------------------------- 549 | longword TS7Server::GetEventsMask() 550 | { 551 | longword Mask; 552 | int Result = Srv_GetMask(Server, mkEvent, &Mask); 553 | if (Result==0) 554 | return Mask; 555 | else 556 | return 0; 557 | } 558 | //--------------------------------------------------------------------------- 559 | longword TS7Server::GetLogMask() 560 | { 561 | longword Mask; 562 | int Result = Srv_GetMask(Server, mkLog, &Mask); 563 | if (Result==0) 564 | return Mask; 565 | else 566 | return 0; 567 | } 568 | //--------------------------------------------------------------------------- 569 | void TS7Server::SetEventsMask(longword Mask) 570 | { 571 | Srv_SetMask(Server, mkEvent, Mask); 572 | } 573 | //--------------------------------------------------------------------------- 574 | void TS7Server::SetLogMask(longword Mask) 575 | { 576 | Srv_SetMask(Server, mkLog, Mask); 577 | } 578 | //--------------------------------------------------------------------------- 579 | int TS7Server::RegisterArea(int AreaCode, word Index, void *pUsrData, word Size) 580 | { 581 | return Srv_RegisterArea(Server, AreaCode, Index, pUsrData, Size); 582 | } 583 | //--------------------------------------------------------------------------- 584 | int TS7Server::UnregisterArea(int AreaCode, word Index) 585 | { 586 | return Srv_UnregisterArea(Server, AreaCode, Index); 587 | } 588 | //--------------------------------------------------------------------------- 589 | int TS7Server::LockArea(int AreaCode, word Index) 590 | { 591 | return Srv_LockArea(Server, AreaCode, Index); 592 | } 593 | //--------------------------------------------------------------------------- 594 | int TS7Server::UnlockArea(int AreaCode, word Index) 595 | { 596 | return Srv_UnlockArea(Server, AreaCode, Index); 597 | } 598 | //--------------------------------------------------------------------------- 599 | int TS7Server::ServerStatus() 600 | { 601 | int ServerStatus, CpuStatus, ClientsCount; 602 | int Result =Srv_GetStatus(Server, &ServerStatus, &CpuStatus, &ClientsCount); 603 | if (Result==0) 604 | return ServerStatus; 605 | else 606 | return Result; 607 | } 608 | //--------------------------------------------------------------------------- 609 | int TS7Server::GetCpuStatus() 610 | { 611 | int ServerStatus, CpuStatus, ClientsCount; 612 | int Result =Srv_GetStatus(Server, &ServerStatus, &CpuStatus, &ClientsCount); 613 | if (Result==0) 614 | return CpuStatus; 615 | else 616 | return Result; 617 | } 618 | //--------------------------------------------------------------------------- 619 | int TS7Server::ClientsCount() 620 | { 621 | int ServerStatus, CpuStatus, ClientsCount; 622 | int Result =Srv_GetStatus(Server, &ServerStatus, &CpuStatus, &ClientsCount); 623 | if (Result==0) 624 | return ClientsCount; 625 | else 626 | return Result; 627 | } 628 | //--------------------------------------------------------------------------- 629 | int TS7Server::SetCpuStatus(int Status) 630 | { 631 | return Srv_SetCpuStatus(Server, Status); 632 | } 633 | //============================================================================== 634 | // PARTNER 635 | //============================================================================== 636 | TS7Partner::TS7Partner(bool Active) 637 | { 638 | Partner=Par_Create(int(Active)); 639 | } 640 | //--------------------------------------------------------------------------- 641 | TS7Partner::~TS7Partner() 642 | { 643 | Par_Destroy(&Partner); 644 | } 645 | //--------------------------------------------------------------------------- 646 | int TS7Partner::GetParam(int ParamNumber, void *pValue) 647 | { 648 | return Par_GetParam(Partner, ParamNumber, pValue); 649 | } 650 | //--------------------------------------------------------------------------- 651 | int TS7Partner::SetParam(int ParamNumber, void *pValue) 652 | { 653 | return Par_SetParam(Partner, ParamNumber, pValue); 654 | } 655 | //--------------------------------------------------------------------------- 656 | int TS7Partner::Start() 657 | { 658 | return Par_Start(Partner); 659 | } 660 | //--------------------------------------------------------------------------- 661 | int TS7Partner::StartTo(const char *LocalAddress, const char *RemoteAddress, int LocalTSAP, int RemoteTSAP) 662 | { 663 | return Par_StartTo(Partner, LocalAddress, RemoteAddress, LocalTSAP, RemoteTSAP); 664 | } 665 | //--------------------------------------------------------------------------- 666 | int TS7Partner::Stop() 667 | { 668 | return Par_Stop(Partner); 669 | } 670 | //--------------------------------------------------------------------------- 671 | int TS7Partner::BSend(longword R_ID, void *pUsrData, int Size) 672 | { 673 | return Par_BSend(Partner, R_ID, pUsrData, Size); 674 | } 675 | //--------------------------------------------------------------------------- 676 | int TS7Partner::AsBSend(longword R_ID, void *pUsrData, int Size) 677 | { 678 | return Par_AsBSend(Partner, R_ID, pUsrData, Size); 679 | } 680 | //--------------------------------------------------------------------------- 681 | bool TS7Partner::CheckAsBSendCompletion(int *opResult) 682 | { 683 | return Par_CheckAsBSendCompletion(Partner ,opResult)==JobComplete; 684 | } 685 | //--------------------------------------------------------------------------- 686 | int TS7Partner::WaitAsBSendCompletion(longword Timeout) 687 | { 688 | return Par_WaitAsBSendCompletion(Partner, Timeout); 689 | } 690 | //--------------------------------------------------------------------------- 691 | int TS7Partner::SetSendCallback(pfn_ParSendCompletion pCompletion, void *usrPtr) 692 | { 693 | return Par_SetSendCallback(Partner, pCompletion, usrPtr); 694 | } 695 | //--------------------------------------------------------------------------- 696 | int TS7Partner::BRecv(longword *R_ID, void *pUsrData, int *Size, longword Timeout) 697 | { 698 | return Par_BRecv(Partner, R_ID, pUsrData, Size, Timeout); 699 | } 700 | //--------------------------------------------------------------------------- 701 | bool TS7Partner::CheckAsBRecvCompletion(int *opResult, longword *R_ID, void *pUsrData, int *Size) 702 | { 703 | return Par_CheckAsBRecvCompletion(Partner, opResult, R_ID, pUsrData, Size) == JobComplete; 704 | } 705 | //--------------------------------------------------------------------------- 706 | int TS7Partner::SetRecvCallback(pfn_ParRecvCallBack pCallback, void *usrPtr) 707 | { 708 | return Par_SetRecvCallback(Partner, pCallback, usrPtr); 709 | } 710 | //--------------------------------------------------------------------------- 711 | int TS7Partner::Status() 712 | { 713 | int ParStatus; 714 | int Result = Par_GetStatus(Partner, &ParStatus); 715 | if (Result==0) 716 | return ParStatus; 717 | else 718 | return Result; 719 | } 720 | //--------------------------------------------------------------------------- 721 | int TS7Partner::LastError() 722 | { 723 | int Error; 724 | int Result = Par_GetLastError(Partner, &Error); 725 | if (Result==0) 726 | return Error; 727 | else 728 | return Result; 729 | } 730 | //--------------------------------------------------------------------------- 731 | int TS7Partner::GetTimes(longword *SendTime, longword *RecvTime) 732 | { 733 | return Par_GetTimes(Partner, SendTime, RecvTime); 734 | } 735 | //--------------------------------------------------------------------------- 736 | int TS7Partner::GetStats(longword *BytesSent, longword *BytesRecv, longword *ErrSend, longword *ErrRecv) 737 | { 738 | return Par_GetStats(Partner, BytesSent, BytesRecv, ErrSend, ErrRecv); 739 | } 740 | //--------------------------------------------------------------------------- 741 | bool TS7Partner::Linked() 742 | { 743 | return Status()==par_linked; 744 | } 745 | //============================================================================== 746 | // Text routines 747 | //============================================================================== 748 | TextString CliErrorText(int Error) 749 | { 750 | char text[TextLen]; 751 | Cli_ErrorText(Error, text, TextLen); 752 | return TextString(text); 753 | } 754 | //--------------------------------------------------------------------------- 755 | TextString SrvErrorText(int Error) 756 | { 757 | char text[TextLen]; 758 | Srv_ErrorText(Error, text, TextLen); 759 | return TextString(text); 760 | } 761 | //--------------------------------------------------------------------------- 762 | TextString ParErrorText(int Error) 763 | { 764 | char text[TextLen]; 765 | Par_ErrorText(Error, text, TextLen); 766 | return TextString(text); 767 | } 768 | //--------------------------------------------------------------------------- 769 | TextString SrvEventText(TSrvEvent *Event) 770 | { 771 | char text[TextLen]; 772 | Srv_EventText(Event, text, TextLen); 773 | return TextString(text); 774 | } 775 | 776 | -------------------------------------------------------------------------------- /translation/translation_it.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abedGNU/QtSnap7/fa9cedc137408377cfe77457e46d1b332a7612ea/translation/translation_it.qm -------------------------------------------------------------------------------- /translation/translation_it.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | MainWindow 6 | 7 | 8 | MainWindow 9 | 10 | 11 | 12 | 13 | PLC data 14 | 15 | 16 | 17 | 18 | 19 | Write 20 | Scrivi 21 | 22 | 23 | 24 | TestCasting 25 | 26 | 27 | 28 | 29 | Ip address 30 | Indirizzo ip 31 | 32 | 33 | 34 | TextLabel 35 | 36 | 37 | 38 | 39 | Language 40 | 41 | 42 | 43 | 44 | 45 | English 46 | Inglese 47 | 48 | 49 | 50 | 51 | Italian 52 | Italiano 53 | 54 | 55 | 56 | PLC IP address 57 | 58 | 59 | 60 | 61 | --------------------------------------------------------------------------------