fakelab 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (251) hide show
  1. fakelab-0.1.0/.flake8 +7 -0
  2. fakelab-0.1.0/.github/FUNDING.yml +12 -0
  3. fakelab-0.1.0/.github/workflows/publish_to_pypi.yml +42 -0
  4. fakelab-0.1.0/.gitignore +13 -0
  5. fakelab-0.1.0/PKG-INFO +309 -0
  6. fakelab-0.1.0/README.md +261 -0
  7. fakelab-0.1.0/doc/Makefile +20 -0
  8. fakelab-0.1.0/doc/make.bat +35 -0
  9. fakelab-0.1.0/doc/source/_autosummary/FL.FLdict.rst +23 -0
  10. fakelab-0.1.0/doc/source/_autosummary/FL.cmdline.FontLab5Console.rst +34 -0
  11. fakelab-0.1.0/doc/source/_autosummary/FL.cmdline.main.rst +6 -0
  12. fakelab-0.1.0/doc/source/_autosummary/FL.cmdline.rst +38 -0
  13. fakelab-0.1.0/doc/source/_autosummary/FL.constants.rst +23 -0
  14. fakelab-0.1.0/doc/source/_autosummary/FL.fake.Base.Copyable.rst +25 -0
  15. fakelab-0.1.0/doc/source/_autosummary/FL.fake.Base.rst +31 -0
  16. fakelab-0.1.0/doc/source/_autosummary/FL.fake.Font.FakeFont.rst +39 -0
  17. fakelab-0.1.0/doc/source/_autosummary/FL.fake.Font.rst +31 -0
  18. fakelab-0.1.0/doc/source/_autosummary/FL.fake.Kerning.FakeKerning.rst +33 -0
  19. fakelab-0.1.0/doc/source/_autosummary/FL.fake.Kerning.rst +31 -0
  20. fakelab-0.1.0/doc/source/_autosummary/FL.fake.KerningClass.KerningClass.rst +35 -0
  21. fakelab-0.1.0/doc/source/_autosummary/FL.fake.KerningClass.rst +31 -0
  22. fakelab-0.1.0/doc/source/_autosummary/FL.fake.rst +35 -0
  23. fakelab-0.1.0/doc/source/_autosummary/FL.fl_cmd.rst +23 -0
  24. fakelab-0.1.0/doc/source/_autosummary/FL.helpers.FLList.FLList.rst +37 -0
  25. fakelab-0.1.0/doc/source/_autosummary/FL.helpers.FLList.adjust_list.rst +6 -0
  26. fakelab-0.1.0/doc/source/_autosummary/FL.helpers.FLList.rst +38 -0
  27. fakelab-0.1.0/doc/source/_autosummary/FL.helpers.ListParent.ListParent.rst +37 -0
  28. fakelab-0.1.0/doc/source/_autosummary/FL.helpers.ListParent.rst +31 -0
  29. fakelab-0.1.0/doc/source/_autosummary/FL.helpers.classList.ClassList.rst +48 -0
  30. fakelab-0.1.0/doc/source/_autosummary/FL.helpers.classList.rst +31 -0
  31. fakelab-0.1.0/doc/source/_autosummary/FL.helpers.nametables.StandardNametable.rst +27 -0
  32. fakelab-0.1.0/doc/source/_autosummary/FL.helpers.nametables.rst +31 -0
  33. fakelab-0.1.0/doc/source/_autosummary/FL.helpers.registry.parse_registry_file.rst +6 -0
  34. fakelab-0.1.0/doc/source/_autosummary/FL.helpers.registry.rst +30 -0
  35. fakelab-0.1.0/doc/source/_autosummary/FL.helpers.rst +37 -0
  36. fakelab-0.1.0/doc/source/_autosummary/FL.helpers.tth.TTCommandDict.rst +43 -0
  37. fakelab-0.1.0/doc/source/_autosummary/FL.helpers.tth.rst +31 -0
  38. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Anchor.Anchor.rst +37 -0
  39. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Anchor.rst +31 -0
  40. fakelab-0.1.0/doc/source/_autosummary/FL.objects.AuditRecord.AuditRecord.rst +39 -0
  41. fakelab-0.1.0/doc/source/_autosummary/FL.objects.AuditRecord.rst +31 -0
  42. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Canvas.Canvas.rst +54 -0
  43. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Canvas.rst +31 -0
  44. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Component.Component.rst +38 -0
  45. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Component.rst +31 -0
  46. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Dialog.Dialog.rst +43 -0
  47. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Dialog.rst +31 -0
  48. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Encoding.Encoding.rst +49 -0
  49. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Encoding.data.rst +6 -0
  50. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Encoding.rst +31 -0
  51. fakelab-0.1.0/doc/source/_autosummary/FL.objects.EncodingRecord.EncodingRecord.rst +32 -0
  52. fakelab-0.1.0/doc/source/_autosummary/FL.objects.EncodingRecord.rst +31 -0
  53. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Feature.Feature.rst +33 -0
  54. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Feature.rst +31 -0
  55. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Font.Font.rst +151 -0
  56. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Font.rst +31 -0
  57. fakelab-0.1.0/doc/source/_autosummary/FL.objects.FontLab.FakeLab.rst +83 -0
  58. fakelab-0.1.0/doc/source/_autosummary/FL.objects.FontLab.rst +31 -0
  59. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Glyph.Glyph.rst +122 -0
  60. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Glyph.rst +31 -0
  61. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Guide.Guide.rst +33 -0
  62. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Guide.rst +31 -0
  63. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Hint.Hint.rst +38 -0
  64. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Hint.rst +31 -0
  65. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Image.Image.rst +25 -0
  66. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Image.rst +31 -0
  67. fakelab-0.1.0/doc/source/_autosummary/FL.objects.KerningPair.KerningPair.rst +35 -0
  68. fakelab-0.1.0/doc/source/_autosummary/FL.objects.KerningPair.rst +31 -0
  69. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Link.Link.rst +35 -0
  70. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Link.rst +31 -0
  71. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Matrix.Matrix.rst +42 -0
  72. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Matrix.rst +31 -0
  73. fakelab-0.1.0/doc/source/_autosummary/FL.objects.NameRecord.NameRecord.rst +36 -0
  74. fakelab-0.1.0/doc/source/_autosummary/FL.objects.NameRecord.rst +31 -0
  75. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Node.Node.rst +49 -0
  76. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Node.rst +31 -0
  77. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Options.Options.rst +203 -0
  78. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Options.rst +31 -0
  79. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Point.Point.rst +40 -0
  80. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Point.rst +31 -0
  81. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Rect.Rect.rst +43 -0
  82. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Rect.rst +31 -0
  83. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Replace.Replace.rst +33 -0
  84. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Replace.rst +31 -0
  85. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTGasp.TTGasp.rst +32 -0
  86. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTGasp.rst +31 -0
  87. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTH.TTH.rst +62 -0
  88. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTH.base_hstems.rst +6 -0
  89. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTH.base_vstems.rst +6 -0
  90. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTH.hstems.rst +6 -0
  91. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTH.rst +31 -0
  92. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTH.vstems.rst +6 -0
  93. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTHCommand.TTHCommand.rst +32 -0
  94. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTHCommand.rst +31 -0
  95. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTHPoint.TTHPoint.rst +34 -0
  96. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTHPoint.rst +31 -0
  97. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTHProblem.TTHProblem.rst +34 -0
  98. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTHProblem.rst +31 -0
  99. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTInfo.TTInfo.rst +75 -0
  100. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTInfo.rst +31 -0
  101. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTPoint.TTPoint.rst +33 -0
  102. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTPoint.rst +31 -0
  103. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTStem.TTStem.rst +38 -0
  104. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTStem.rst +31 -0
  105. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTVdmx.TTVdmx.rst +33 -0
  106. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TTVdmx.rst +31 -0
  107. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TrueTypeTable.TrueTypeTable.rst +33 -0
  108. fakelab-0.1.0/doc/source/_autosummary/FL.objects.TrueTypeTable.rst +31 -0
  109. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Uni.Uni.rst +31 -0
  110. fakelab-0.1.0/doc/source/_autosummary/FL.objects.Uni.rst +31 -0
  111. fakelab-0.1.0/doc/source/_autosummary/FL.objects.WeightVector.WeightVector.rst +31 -0
  112. fakelab-0.1.0/doc/source/_autosummary/FL.objects.WeightVector.rst +31 -0
  113. fakelab-0.1.0/doc/source/_autosummary/FL.objects.rst +66 -0
  114. fakelab-0.1.0/doc/source/_autosummary/FL.vfb.reader.VfbToFontReader.rst +27 -0
  115. fakelab-0.1.0/doc/source/_autosummary/FL.vfb.reader.rst +31 -0
  116. fakelab-0.1.0/doc/source/_autosummary/FL.vfb.rst +33 -0
  117. fakelab-0.1.0/doc/source/_autosummary/FL.vfb.writer.FontToVfbWriter.rst +34 -0
  118. fakelab-0.1.0/doc/source/_autosummary/FL.vfb.writer.rst +31 -0
  119. fakelab-0.1.0/doc/source/_templates/custom-class-template.rst +32 -0
  120. fakelab-0.1.0/doc/source/_templates/custom-module-template.rst +66 -0
  121. fakelab-0.1.0/doc/source/api.rst +16 -0
  122. fakelab-0.1.0/doc/source/conf.py +36 -0
  123. fakelab-0.1.0/doc/source/index.rst +3 -0
  124. fakelab-0.1.0/doc/source/usage.rst +23 -0
  125. fakelab-0.1.0/doc/truetype-hinting/fdef0.md +37 -0
  126. fakelab-0.1.0/doc/truetype-hinting/fdef1.md +25 -0
  127. fakelab-0.1.0/doc/truetype-hinting/fdef2.md +17 -0
  128. fakelab-0.1.0/doc/truetype-hinting/fdef3.md +79 -0
  129. fakelab-0.1.0/doc/truetype-hinting/fdef4.md +47 -0
  130. fakelab-0.1.0/doc/truetype-hinting/fdef5.md +46 -0
  131. fakelab-0.1.0/doc/truetype-hinting/fdef6.md +33 -0
  132. fakelab-0.1.0/doc/truetype-hinting/fdef7.md +18 -0
  133. fakelab-0.1.0/doc/truetype-hinting/fdef8.md +128 -0
  134. fakelab-0.1.0/doc/truetype-hinting/fdef9.md +24 -0
  135. fakelab-0.1.0/doc/truetype-hinting/fpgm.md +14 -0
  136. fakelab-0.1.0/doc/truetype-hinting/index.md +617 -0
  137. fakelab-0.1.0/doc/truetype-hinting/prep.md +130 -0
  138. fakelab-0.1.0/doc/truetype-hinting/tth-colon.webp +0 -0
  139. fakelab-0.1.0/doc/truetype-hinting/tth-e.webp +0 -0
  140. fakelab-0.1.0/doc/truetype-hinting/tth-f.webp +0 -0
  141. fakelab-0.1.0/doc/truetype-hinting/tth-k.webp +0 -0
  142. fakelab-0.1.0/doc/truetype-hinting/tth-o.webp +0 -0
  143. fakelab-0.1.0/doc/truetype-hinting/tth-options-general.webp +0 -0
  144. fakelab-0.1.0/doc/truetype-hinting/tth-options-stems.webp +0 -0
  145. fakelab-0.1.0/doc/truetype-hinting/tth-options-zones.webp +0 -0
  146. fakelab-0.1.0/examples/Macros/Selection/Select composites.py +3 -0
  147. fakelab-0.1.0/examples/Macros/System/Modules/fakeLabDemo/__init__.py +0 -0
  148. fakelab-0.1.0/examples/Macros/System/Modules/fakeLabDemo/selection/__init__.py +0 -0
  149. fakelab-0.1.0/examples/Macros/System/Modules/fakeLabDemo/selection/composites.py +49 -0
  150. fakelab-0.1.0/examples/Macros/System/Modules/tests/fakeLabDemo/selection/composites_test.py +46 -0
  151. fakelab-0.1.0/pyproject.toml +185 -0
  152. fakelab-0.1.0/setup.cfg +4 -0
  153. fakelab-0.1.0/src/FL/FLdict.py +214 -0
  154. fakelab-0.1.0/src/FL/__init__.py +344 -0
  155. fakelab-0.1.0/src/FL/_version.py +34 -0
  156. fakelab-0.1.0/src/FL/cmdline.py +124 -0
  157. fakelab-0.1.0/src/FL/constants.py +31 -0
  158. fakelab-0.1.0/src/FL/fake/Base.py +20 -0
  159. fakelab-0.1.0/src/FL/fake/Font.py +153 -0
  160. fakelab-0.1.0/src/FL/fake/Kerning.py +232 -0
  161. fakelab-0.1.0/src/FL/fake/KerningClass.py +163 -0
  162. fakelab-0.1.0/src/FL/fake/__init__.py +0 -0
  163. fakelab-0.1.0/src/FL/fake/mixins.py +74 -0
  164. fakelab-0.1.0/src/FL/fl_cmd.py +494 -0
  165. fakelab-0.1.0/src/FL/helpers/FLList.py +40 -0
  166. fakelab-0.1.0/src/FL/helpers/ListParent.py +61 -0
  167. fakelab-0.1.0/src/FL/helpers/__init__.py +1 -0
  168. fakelab-0.1.0/src/FL/helpers/classList.py +186 -0
  169. fakelab-0.1.0/src/FL/helpers/math.py +15 -0
  170. fakelab-0.1.0/src/FL/helpers/nametables.py +6099 -0
  171. fakelab-0.1.0/src/FL/helpers/registry.py +409 -0
  172. fakelab-0.1.0/src/FL/helpers/tth.py +67 -0
  173. fakelab-0.1.0/src/FL/objects/Anchor.py +181 -0
  174. fakelab-0.1.0/src/FL/objects/AuditRecord.py +129 -0
  175. fakelab-0.1.0/src/FL/objects/Canvas.py +360 -0
  176. fakelab-0.1.0/src/FL/objects/Component.py +212 -0
  177. fakelab-0.1.0/src/FL/objects/Dialog.py +165 -0
  178. fakelab-0.1.0/src/FL/objects/Encoding.py +395 -0
  179. fakelab-0.1.0/src/FL/objects/EncodingRecord.py +56 -0
  180. fakelab-0.1.0/src/FL/objects/Feature.py +81 -0
  181. fakelab-0.1.0/src/FL/objects/Font.py +1006 -0
  182. fakelab-0.1.0/src/FL/objects/FontLab.py +688 -0
  183. fakelab-0.1.0/src/FL/objects/Glyph.py +1580 -0
  184. fakelab-0.1.0/src/FL/objects/Guide.py +166 -0
  185. fakelab-0.1.0/src/FL/objects/Hint.py +202 -0
  186. fakelab-0.1.0/src/FL/objects/Image.py +240 -0
  187. fakelab-0.1.0/src/FL/objects/KerningPair.py +106 -0
  188. fakelab-0.1.0/src/FL/objects/Link.py +87 -0
  189. fakelab-0.1.0/src/FL/objects/Matrix.py +263 -0
  190. fakelab-0.1.0/src/FL/objects/NameRecord.py +145 -0
  191. fakelab-0.1.0/src/FL/objects/Node.py +244 -0
  192. fakelab-0.1.0/src/FL/objects/Options.py +1818 -0
  193. fakelab-0.1.0/src/FL/objects/Point.py +182 -0
  194. fakelab-0.1.0/src/FL/objects/Rect.py +227 -0
  195. fakelab-0.1.0/src/FL/objects/Replace.py +123 -0
  196. fakelab-0.1.0/src/FL/objects/TTGasp.py +91 -0
  197. fakelab-0.1.0/src/FL/objects/TTH.py +450 -0
  198. fakelab-0.1.0/src/FL/objects/TTHCommand.py +79 -0
  199. fakelab-0.1.0/src/FL/objects/TTHPoint.py +132 -0
  200. fakelab-0.1.0/src/FL/objects/TTHProblem.py +48 -0
  201. fakelab-0.1.0/src/FL/objects/TTInfo.py +833 -0
  202. fakelab-0.1.0/src/FL/objects/TTPoint.py +80 -0
  203. fakelab-0.1.0/src/FL/objects/TTStem.py +189 -0
  204. fakelab-0.1.0/src/FL/objects/TTVdmx.py +62 -0
  205. fakelab-0.1.0/src/FL/objects/TrueTypeTable.py +82 -0
  206. fakelab-0.1.0/src/FL/objects/Uni.py +82 -0
  207. fakelab-0.1.0/src/FL/objects/WeightVector.py +52 -0
  208. fakelab-0.1.0/src/FL/objects/__init__.py +0 -0
  209. fakelab-0.1.0/src/FL/py.typed +0 -0
  210. fakelab-0.1.0/src/FL/vfb/__init__.py +0 -0
  211. fakelab-0.1.0/src/FL/vfb/reader.py +319 -0
  212. fakelab-0.1.0/src/FL/vfb/writer.py +315 -0
  213. fakelab-0.1.0/src/fakelab.egg-info/PKG-INFO +309 -0
  214. fakelab-0.1.0/src/fakelab.egg-info/SOURCES.txt +249 -0
  215. fakelab-0.1.0/src/fakelab.egg-info/dependency_links.txt +1 -0
  216. fakelab-0.1.0/src/fakelab.egg-info/entry_points.txt +2 -0
  217. fakelab-0.1.0/src/fakelab.egg-info/requires.txt +34 -0
  218. fakelab-0.1.0/src/fakelab.egg-info/top_level.txt +1 -0
  219. fakelab-0.1.0/tests/data/Untitled.reg +333 -0
  220. fakelab-0.1.0/tests/data/empty.reg +0 -0
  221. fakelab-0.1.0/tests/data/empty.vfb +0 -0
  222. fakelab-0.1.0/tests/data/mini.vfb +0 -0
  223. fakelab-0.1.0/tests/data/mini.vfb.json +3376 -0
  224. fakelab-0.1.0/tests/data/minimal.reg +6 -0
  225. fakelab-0.1.0/tests/data/nokey.reg +3 -0
  226. fakelab-0.1.0/tests/data/wrong_header.reg +3 -0
  227. fakelab-0.1.0/tests/data/wrong_value_type.reg +6 -0
  228. fakelab-0.1.0/tests/fake/classes.flc +19 -0
  229. fakelab-0.1.0/tests/fake/kerning_class_test.py +20 -0
  230. fakelab-0.1.0/tests/fake/kerning_test.py +45 -0
  231. fakelab-0.1.0/tests/fl_test.py +321 -0
  232. fakelab-0.1.0/tests/helpers/FLList_test.py +51 -0
  233. fakelab-0.1.0/tests/helpers/ListParent_test.py +0 -0
  234. fakelab-0.1.0/tests/helpers/classList_test.py +107 -0
  235. fakelab-0.1.0/tests/helpers/math_test.py +29 -0
  236. fakelab-0.1.0/tests/helpers/nametables_test.py +64 -0
  237. fakelab-0.1.0/tests/helpers/registry_test.py +35 -0
  238. fakelab-0.1.0/tests/objects/font_test.py +511 -0
  239. fakelab-0.1.0/tests/objects/glyph_test.py +38 -0
  240. fakelab-0.1.0/tests/objects/guide_test.py +54 -0
  241. fakelab-0.1.0/tests/objects/hint_test.py +43 -0
  242. fakelab-0.1.0/tests/objects/kerningpair_test.py +14 -0
  243. fakelab-0.1.0/tests/objects/matrix_test.py +179 -0
  244. fakelab-0.1.0/tests/objects/node_test.py +23 -0
  245. fakelab-0.1.0/tests/objects/options_test.py +41 -0
  246. fakelab-0.1.0/tests/objects/point_test.py +77 -0
  247. fakelab-0.1.0/tests/objects/rect_test.py +106 -0
  248. fakelab-0.1.0/tests/objects/ttgasp_test.py +29 -0
  249. fakelab-0.1.0/tests/objects/tthcommand_test.py +26 -0
  250. fakelab-0.1.0/tests/objects/ttstem_test.py +49 -0
  251. fakelab-0.1.0/tox.ini +40 -0
fakelab-0.1.0/.flake8 ADDED
@@ -0,0 +1,7 @@
1
+ [flake8]
2
+ select = B, C, E, F, W, T4, B9
3
+ # last two ignores: * imports, unused imports
4
+ ignore = E203, E266, E501, W503, E741, F403, F401
5
+ max-line-length = 88
6
+ max-complexity = 19
7
+ exclude = .git, __pycache__, build, dist, .eggs, .tox
@@ -0,0 +1,12 @@
1
+ # These are supported funding model platforms
2
+
3
+ github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4
+ patreon: # Replace with a single Patreon username
5
+ open_collective: # Replace with a single Open Collective username
6
+ ko_fi: jenskutilek
7
+ tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8
+ community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9
+ liberapay: # Replace with a single Liberapay username
10
+ issuehunt: # Replace with a single IssueHunt username
11
+ otechie: # Replace with a single Otechie username
12
+ custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
@@ -0,0 +1,42 @@
1
+ name: Publish packages to PyPI
2
+
3
+ on: push
4
+
5
+ jobs:
6
+ build-n-publish:
7
+ name: Build and publish distribution packages
8
+ if: github.repository == 'jenskutilek/fakelab'
9
+ runs-on: ubuntu-latest
10
+ environment:
11
+ name: pypi
12
+ url: https://pypi.org/p/fakelab
13
+ permissions:
14
+ id-token: write
15
+ steps:
16
+ - uses: actions/checkout@v5
17
+ with:
18
+ fetch-depth: 0
19
+ - name: Set up Python 3.12
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: 3.12
23
+
24
+ - name: Install pypa/build
25
+ run: >-
26
+ python -m
27
+ pip install
28
+ build
29
+ --user
30
+
31
+ - name: Build a binary wheel and a source tarball
32
+ run: >-
33
+ python -m
34
+ build
35
+ --sdist
36
+ --wheel
37
+ --outdir dist/
38
+ .
39
+
40
+ - name: Publish distribution package to PyPI
41
+ if: startsWith(github.ref, 'refs/tags')
42
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,13 @@
1
+ __pycache__
2
+ *.egg-info/
3
+ .tox
4
+ build/
5
+ dist/
6
+ .coverage.*
7
+ .coverage
8
+ .mypy_cache
9
+ .vscode
10
+ venv/
11
+ src/FL/_version.py
12
+ exe/
13
+ doc/build
fakelab-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,309 @@
1
+ Metadata-Version: 2.4
2
+ Name: fakelab
3
+ Version: 0.1.0
4
+ Summary: Fake FontLab Studio 5 for automated tests and external scripting
5
+ Author-email: Jens Kutílek <webmail@kutilek.de>
6
+ License-Expression: GPL-3.0-or-later
7
+ Project-URL: Homepage, https://github.com/jenskutilek/fakelab
8
+ Project-URL: Documentation, https://fakelab.readthedocs.io/
9
+ Project-URL: Bug Tracker, https://github.com/jenskutilek/fakelab/issues
10
+ Project-URL: Changelog, https://github.com/jenskutilek/fakelab/blob/develop/docs/CHANGELOG.md
11
+ Keywords: vfb,fonttools
12
+ Classifier: Environment :: Console
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python
15
+ Classifier: Programming Language :: Python :: 3 :: Only
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Requires-Python: >=3.11
20
+ Description-Content-Type: text/markdown
21
+ Provides-Extra: all
22
+ Requires-Dist: fakelab[generate]; extra == "all"
23
+ Requires-Dist: fakelab[repl]; extra == "all"
24
+ Requires-Dist: fakelab[vfb]; extra == "all"
25
+ Provides-Extra: generate
26
+ Requires-Dist: ufo2ft>=3.6.0; extra == "generate"
27
+ Requires-Dist: fakelab[vfb]; extra == "generate"
28
+ Provides-Extra: repl
29
+ Requires-Dist: ptpython>=3.0.30; extra == "repl"
30
+ Provides-Extra: vfb
31
+ Requires-Dist: vfbLib>=0.10.3; extra == "vfb"
32
+ Provides-Extra: test
33
+ Requires-Dist: mypy; extra == "test"
34
+ Requires-Dist: pytest; extra == "test"
35
+ Requires-Dist: pytest-black-ng; extra == "test"
36
+ Requires-Dist: pytest-cov; extra == "test"
37
+ Requires-Dist: pytest-isort; extra == "test"
38
+ Requires-Dist: pytest-mock; extra == "test"
39
+ Requires-Dist: pytest-mypy; extra == "test"
40
+ Requires-Dist: pytest-pylint; extra == "test"
41
+ Provides-Extra: dev
42
+ Requires-Dist: build; extra == "dev"
43
+ Requires-Dist: wheel; extra == "dev"
44
+ Requires-Dist: setuptools-scm[toml]; extra == "dev"
45
+ Provides-Extra: doc
46
+ Requires-Dist: sphinx>=8.1.3; extra == "doc"
47
+ Requires-Dist: sphinx_rtd_theme; extra == "doc"
48
+
49
+ # FakeLab
50
+
51
+ Test-driven development for FontLab Studio 5 Python macros and modules.
52
+
53
+ FakeLab is a FontLab Studio 5 replacement for testing Python code.
54
+
55
+ Everything is only implemented so far as to make FontLab objects importable
56
+ outside of FontLab Studio 5, and run tests.
57
+
58
+ It is suggested to install FakeLab in a virtual environment so FontLab won't
59
+ accidentally import the fake module when running the scripts in actual FontLab
60
+ Studio 5. If you can live with the incompatibilites between Python 2.7 and 3,
61
+ you can also run FakeLab in Python 3.
62
+
63
+ Saving VFBs is not supported, as the VFB format is not public, but you can save
64
+ `Font` objects as JSON.
65
+
66
+ The implementation of FakeLab is based on the invaluable
67
+ [Unofficial FontLab/Python API Reference](http://www.e-font.de/flpydoc/), and
68
+ from running scripts in FontLab Studio and checking what they do, apart from
69
+ crashing the application.
70
+
71
+ ## Installation
72
+
73
+ When you have activated your virtual environment:
74
+
75
+ ```bash
76
+ $ pip install -e .
77
+ ```
78
+
79
+ FL is then importable outside of FontLab Studio:
80
+
81
+ ```python
82
+ from FL import fl, Font
83
+
84
+ # Make an empty font
85
+ f = Font()
86
+
87
+ # Add the font to the mock app
88
+ fl.Add(f)
89
+
90
+ # Close the font
91
+ fl.Close()
92
+ ```
93
+
94
+ If your are running in a virtual environment, and need to make your FontLab
95
+ modules importable, add a `.pth` file in your virtual environment's site-packages
96
+ directory:
97
+
98
+ ```
99
+ # fl5modules.pth
100
+ /Users/<yourname>/Code/FLMacros/System/Modules
101
+ ```
102
+
103
+ ## A word of caution
104
+
105
+ FakeLab is a work in progress, and only implemented as far as I needed it in my
106
+ own scripts. I have to admit that the bulk of them still has no tests.
107
+
108
+ If you encounter a `NotImplementedError` while writing tests, this is where you
109
+ can excel at helping to improve this project ;) I'll be happy to accept your
110
+ [pull requests](https://github.com/jenskutilek/fakelab/pulls). Alternatively,
111
+ [open an issue](https://github.com/jenskutilek/fakelab/issues),
112
+ [buy me a coffee](https://ko-fi.com/jenskutilek), and hope that my kids leave
113
+ me alone so I can find some time to work on your issue.
114
+
115
+ ## Writing tests
116
+
117
+ Developing scripts without automated testing is really only for very small
118
+ projects. To be sure of the outcomes of a module or script, you should always
119
+ write tests. This is usually done using
120
+ [pytest](https://docs.pytest.org/en/stable/).
121
+
122
+ ### Tests example
123
+
124
+ Let's assume you have a FontLab script to select glyphs containing components.
125
+ If you have your own tools collection for FontLab, this script may consist of
126
+ two parts: One script that is listed in FontLab's macro toolbar, and one Python
127
+ module implementing the logic, which is called by the toolbar script.
128
+
129
+ ```
130
+ Studio 5
131
+ +- Macros
132
+ +- Selection
133
+ +- Select Composites.py
134
+ +- System
135
+ +- Modules
136
+ +- fakeLabDemo
137
+ +- selection
138
+ +- __init__.py
139
+ +- composites.py
140
+ ```
141
+
142
+ The `Select Composites.py` script looks like this:
143
+
144
+ ```python
145
+ #FLM: Select composites
146
+ # Studio 5/Macros/Selection/Select Composites.py
147
+ from fakeLabDemo.selection.composites import selectComposites
148
+ selectComposites(fl.font)
149
+ ```
150
+
151
+ And the module:
152
+ ```python
153
+ # Studio 5/Macros/System/Modules/fakeLabDemo/selection/composites.py
154
+ from __future__ import absolute_import, division, print_function
155
+
156
+ from FL import fl
157
+
158
+
159
+ def getFontIndex(font):
160
+ """
161
+ Get the index of the supplied font.
162
+ We must iterate through the open fonts and compare file names,
163
+ because the == operator can not compare the font objects directly.
164
+ (FL font objects get a different id() each time they are called)
165
+
166
+ :param font: A title for the dialog.
167
+ :type font: :py:class:`FL.Font`
168
+ """
169
+ for i in range(len(fl)):
170
+ cf = fl[i]
171
+ if cf.file_name == font.file_name:
172
+ if font.file_name is None:
173
+ if (
174
+ cf.family_name == font.family_name
175
+ and cf.style_name == font.style_name
176
+ ):
177
+ return (cf, i)
178
+ else:
179
+ return (cf, i)
180
+ # Font was not found, probably there are no open fonts
181
+ return (None, -1)
182
+
183
+
184
+ def setSelection(font, glyph_names):
185
+ """
186
+ Set glyphs from the glyph_names list as selected in the font window.
187
+ """
188
+ f, i = getFontIndex(font)
189
+ if i > -1:
190
+ fl.ifont = i
191
+ fl.Unselect()
192
+ for n in glyph_names:
193
+ fl.Select(n)
194
+
195
+
196
+ def selectComposites(font):
197
+ """
198
+ Select composites in font.
199
+ """
200
+ setSelection(
201
+ font,
202
+ [
203
+ glyph.name
204
+ for glyph in font.glyphs
205
+ if glyph.components
206
+ ]
207
+ )
208
+ ```
209
+
210
+ How can we be sure this script does what it is supposed to do? For pytest, we
211
+ add another parallel folder structure to the existing structure:
212
+
213
+ ```
214
+ Studio 5
215
+ +- Macros
216
+ +- Selection
217
+ +- Select Composites.py
218
+ +- System
219
+ +- Modules
220
+ +- fakeLabDemo
221
+ +- selection
222
+ +- __init__.py
223
+ +- composites.py
224
+ +- tests
225
+ +- fakeLabDemo
226
+ +- selection
227
+ +- composites_test.py
228
+ ```
229
+
230
+ The file `composites_test.py`, which is named analogous to the module file it
231
+ relates to, is where we will implement our tests:
232
+
233
+ ```python
234
+ # Studio 5/Macros/System/Modules/tests/fakeLabDemo/selection/composites_test.py
235
+ import pytest
236
+
237
+ from FL import fl, Component, Font, Glyph, Point
238
+ from fakeLabDemo.selection.composites import selectComposites
239
+
240
+
241
+ def test_selectComposites():
242
+ # Construct a fake FontLab font object
243
+ font = Font()
244
+ g = Glyph(1)
245
+ g.name = "A"
246
+ g.width = 500
247
+ g.unicode = 0x41
248
+ font.glyphs.append(g)
249
+
250
+ g = Glyph(1)
251
+ g.name = "dieresis"
252
+ g.width = 500
253
+ g.unicode = 0xA8
254
+ font.glyphs.append(g)
255
+
256
+ g = Glyph(1)
257
+ g.name = "Adieresis"
258
+ g.width = 500
259
+ g.unicode = 0xC4
260
+ g.components.append(Component(0))
261
+ g.components.append(Component(1, Point(0, 300)))
262
+ font.glyphs.append(g)
263
+
264
+ # Add the font to the FL object
265
+ fl.Add(font)
266
+ fl.UpdateFont()
267
+
268
+ # Run our script to be tested on the font
269
+ selectComposites(fl.font)
270
+
271
+ # You could save the fake font to JSON instead of VFB.
272
+ # fl.font.Save("test_composites.vfb.json")
273
+
274
+ # Test if the correct glyphs have been selected
275
+ assert fl.Selected(0) == 0
276
+ assert fl.Selected(1) == 0
277
+ assert fl.Selected(2) == 1
278
+
279
+ # Close the fake font
280
+ fl.Close()
281
+ ```
282
+
283
+ As you see, you can use the objects just as you would inside FontLab. You just
284
+ can not open a font from an existing VFB, which would be much easier. But the
285
+ VFB file format is not public.
286
+
287
+ Instead, you have to construct a test font using the
288
+ [FL Python API](http://www.e-font.de/flpydoc/).
289
+
290
+ Invoke the test script in a Terminal window while your virtual environment is
291
+ active:
292
+
293
+ ```bash
294
+ cd "Studio 5/Macros/System/Modules"
295
+ python -m pytest tests/fakeLabDemo/selection/composites_test.py
296
+ ```
297
+
298
+ If everything works out, you will see some output like this:
299
+
300
+ ```
301
+ ============================ test session starts ===============================
302
+ platform darwin -- Python 3.8.7, pytest-6.0.1, py-1.9.0, pluggy-0.13.1
303
+ rootdir: /Users/jens/Code/fakelab
304
+ collected 1 item
305
+
306
+ tests/fakeLabDemo/selection/composites_test.py . [100%]
307
+
308
+ ============================= 1 passed in 0.02s ================================
309
+ ```
@@ -0,0 +1,261 @@
1
+ # FakeLab
2
+
3
+ Test-driven development for FontLab Studio 5 Python macros and modules.
4
+
5
+ FakeLab is a FontLab Studio 5 replacement for testing Python code.
6
+
7
+ Everything is only implemented so far as to make FontLab objects importable
8
+ outside of FontLab Studio 5, and run tests.
9
+
10
+ It is suggested to install FakeLab in a virtual environment so FontLab won't
11
+ accidentally import the fake module when running the scripts in actual FontLab
12
+ Studio 5. If you can live with the incompatibilites between Python 2.7 and 3,
13
+ you can also run FakeLab in Python 3.
14
+
15
+ Saving VFBs is not supported, as the VFB format is not public, but you can save
16
+ `Font` objects as JSON.
17
+
18
+ The implementation of FakeLab is based on the invaluable
19
+ [Unofficial FontLab/Python API Reference](http://www.e-font.de/flpydoc/), and
20
+ from running scripts in FontLab Studio and checking what they do, apart from
21
+ crashing the application.
22
+
23
+ ## Installation
24
+
25
+ When you have activated your virtual environment:
26
+
27
+ ```bash
28
+ $ pip install -e .
29
+ ```
30
+
31
+ FL is then importable outside of FontLab Studio:
32
+
33
+ ```python
34
+ from FL import fl, Font
35
+
36
+ # Make an empty font
37
+ f = Font()
38
+
39
+ # Add the font to the mock app
40
+ fl.Add(f)
41
+
42
+ # Close the font
43
+ fl.Close()
44
+ ```
45
+
46
+ If your are running in a virtual environment, and need to make your FontLab
47
+ modules importable, add a `.pth` file in your virtual environment's site-packages
48
+ directory:
49
+
50
+ ```
51
+ # fl5modules.pth
52
+ /Users/<yourname>/Code/FLMacros/System/Modules
53
+ ```
54
+
55
+ ## A word of caution
56
+
57
+ FakeLab is a work in progress, and only implemented as far as I needed it in my
58
+ own scripts. I have to admit that the bulk of them still has no tests.
59
+
60
+ If you encounter a `NotImplementedError` while writing tests, this is where you
61
+ can excel at helping to improve this project ;) I'll be happy to accept your
62
+ [pull requests](https://github.com/jenskutilek/fakelab/pulls). Alternatively,
63
+ [open an issue](https://github.com/jenskutilek/fakelab/issues),
64
+ [buy me a coffee](https://ko-fi.com/jenskutilek), and hope that my kids leave
65
+ me alone so I can find some time to work on your issue.
66
+
67
+ ## Writing tests
68
+
69
+ Developing scripts without automated testing is really only for very small
70
+ projects. To be sure of the outcomes of a module or script, you should always
71
+ write tests. This is usually done using
72
+ [pytest](https://docs.pytest.org/en/stable/).
73
+
74
+ ### Tests example
75
+
76
+ Let's assume you have a FontLab script to select glyphs containing components.
77
+ If you have your own tools collection for FontLab, this script may consist of
78
+ two parts: One script that is listed in FontLab's macro toolbar, and one Python
79
+ module implementing the logic, which is called by the toolbar script.
80
+
81
+ ```
82
+ Studio 5
83
+ +- Macros
84
+ +- Selection
85
+ +- Select Composites.py
86
+ +- System
87
+ +- Modules
88
+ +- fakeLabDemo
89
+ +- selection
90
+ +- __init__.py
91
+ +- composites.py
92
+ ```
93
+
94
+ The `Select Composites.py` script looks like this:
95
+
96
+ ```python
97
+ #FLM: Select composites
98
+ # Studio 5/Macros/Selection/Select Composites.py
99
+ from fakeLabDemo.selection.composites import selectComposites
100
+ selectComposites(fl.font)
101
+ ```
102
+
103
+ And the module:
104
+ ```python
105
+ # Studio 5/Macros/System/Modules/fakeLabDemo/selection/composites.py
106
+ from __future__ import absolute_import, division, print_function
107
+
108
+ from FL import fl
109
+
110
+
111
+ def getFontIndex(font):
112
+ """
113
+ Get the index of the supplied font.
114
+ We must iterate through the open fonts and compare file names,
115
+ because the == operator can not compare the font objects directly.
116
+ (FL font objects get a different id() each time they are called)
117
+
118
+ :param font: A title for the dialog.
119
+ :type font: :py:class:`FL.Font`
120
+ """
121
+ for i in range(len(fl)):
122
+ cf = fl[i]
123
+ if cf.file_name == font.file_name:
124
+ if font.file_name is None:
125
+ if (
126
+ cf.family_name == font.family_name
127
+ and cf.style_name == font.style_name
128
+ ):
129
+ return (cf, i)
130
+ else:
131
+ return (cf, i)
132
+ # Font was not found, probably there are no open fonts
133
+ return (None, -1)
134
+
135
+
136
+ def setSelection(font, glyph_names):
137
+ """
138
+ Set glyphs from the glyph_names list as selected in the font window.
139
+ """
140
+ f, i = getFontIndex(font)
141
+ if i > -1:
142
+ fl.ifont = i
143
+ fl.Unselect()
144
+ for n in glyph_names:
145
+ fl.Select(n)
146
+
147
+
148
+ def selectComposites(font):
149
+ """
150
+ Select composites in font.
151
+ """
152
+ setSelection(
153
+ font,
154
+ [
155
+ glyph.name
156
+ for glyph in font.glyphs
157
+ if glyph.components
158
+ ]
159
+ )
160
+ ```
161
+
162
+ How can we be sure this script does what it is supposed to do? For pytest, we
163
+ add another parallel folder structure to the existing structure:
164
+
165
+ ```
166
+ Studio 5
167
+ +- Macros
168
+ +- Selection
169
+ +- Select Composites.py
170
+ +- System
171
+ +- Modules
172
+ +- fakeLabDemo
173
+ +- selection
174
+ +- __init__.py
175
+ +- composites.py
176
+ +- tests
177
+ +- fakeLabDemo
178
+ +- selection
179
+ +- composites_test.py
180
+ ```
181
+
182
+ The file `composites_test.py`, which is named analogous to the module file it
183
+ relates to, is where we will implement our tests:
184
+
185
+ ```python
186
+ # Studio 5/Macros/System/Modules/tests/fakeLabDemo/selection/composites_test.py
187
+ import pytest
188
+
189
+ from FL import fl, Component, Font, Glyph, Point
190
+ from fakeLabDemo.selection.composites import selectComposites
191
+
192
+
193
+ def test_selectComposites():
194
+ # Construct a fake FontLab font object
195
+ font = Font()
196
+ g = Glyph(1)
197
+ g.name = "A"
198
+ g.width = 500
199
+ g.unicode = 0x41
200
+ font.glyphs.append(g)
201
+
202
+ g = Glyph(1)
203
+ g.name = "dieresis"
204
+ g.width = 500
205
+ g.unicode = 0xA8
206
+ font.glyphs.append(g)
207
+
208
+ g = Glyph(1)
209
+ g.name = "Adieresis"
210
+ g.width = 500
211
+ g.unicode = 0xC4
212
+ g.components.append(Component(0))
213
+ g.components.append(Component(1, Point(0, 300)))
214
+ font.glyphs.append(g)
215
+
216
+ # Add the font to the FL object
217
+ fl.Add(font)
218
+ fl.UpdateFont()
219
+
220
+ # Run our script to be tested on the font
221
+ selectComposites(fl.font)
222
+
223
+ # You could save the fake font to JSON instead of VFB.
224
+ # fl.font.Save("test_composites.vfb.json")
225
+
226
+ # Test if the correct glyphs have been selected
227
+ assert fl.Selected(0) == 0
228
+ assert fl.Selected(1) == 0
229
+ assert fl.Selected(2) == 1
230
+
231
+ # Close the fake font
232
+ fl.Close()
233
+ ```
234
+
235
+ As you see, you can use the objects just as you would inside FontLab. You just
236
+ can not open a font from an existing VFB, which would be much easier. But the
237
+ VFB file format is not public.
238
+
239
+ Instead, you have to construct a test font using the
240
+ [FL Python API](http://www.e-font.de/flpydoc/).
241
+
242
+ Invoke the test script in a Terminal window while your virtual environment is
243
+ active:
244
+
245
+ ```bash
246
+ cd "Studio 5/Macros/System/Modules"
247
+ python -m pytest tests/fakeLabDemo/selection/composites_test.py
248
+ ```
249
+
250
+ If everything works out, you will see some output like this:
251
+
252
+ ```
253
+ ============================ test session starts ===============================
254
+ platform darwin -- Python 3.8.7, pytest-6.0.1, py-1.9.0, pluggy-0.13.1
255
+ rootdir: /Users/jens/Code/fakelab
256
+ collected 1 item
257
+
258
+ tests/fakeLabDemo/selection/composites_test.py . [100%]
259
+
260
+ ============================= 1 passed in 0.02s ================================
261
+ ```
@@ -0,0 +1,20 @@
1
+ # Minimal makefile for Sphinx documentation
2
+ #
3
+
4
+ # You can set these variables from the command line, and also
5
+ # from the environment for the first two.
6
+ SPHINXOPTS ?=
7
+ SPHINXBUILD ?= sphinx-build
8
+ SOURCEDIR = source
9
+ BUILDDIR = build
10
+
11
+ # Put it first so that "make" without argument is like "make help".
12
+ help:
13
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14
+
15
+ .PHONY: help Makefile
16
+
17
+ # Catch-all target: route all unknown targets to Sphinx using the new
18
+ # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19
+ %: Makefile
20
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@@ -0,0 +1,35 @@
1
+ @ECHO OFF
2
+
3
+ pushd %~dp0
4
+
5
+ REM Command file for Sphinx documentation
6
+
7
+ if "%SPHINXBUILD%" == "" (
8
+ set SPHINXBUILD=sphinx-build
9
+ )
10
+ set SOURCEDIR=source
11
+ set BUILDDIR=build
12
+
13
+ if "%1" == "" goto help
14
+
15
+ %SPHINXBUILD% >NUL 2>NUL
16
+ if errorlevel 9009 (
17
+ echo.
18
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
19
+ echo.installed, then set the SPHINXBUILD environment variable to point
20
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
21
+ echo.may add the Sphinx directory to PATH.
22
+ echo.
23
+ echo.If you don't have Sphinx installed, grab it from
24
+ echo.http://sphinx-doc.org/
25
+ exit /b 1
26
+ )
27
+
28
+ %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
29
+ goto end
30
+
31
+ :help
32
+ %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
33
+
34
+ :end
35
+ popd