{ "info": { "author": "C. Ecker", "author_email": "textmodelview@gmail.com", "bugtrack_url": null, "classifiers": [], "description": "Text Model\r\n==========\r\n\r\nQuick example\r\n-------------\r\n\r\n::\r\n\r\n >>> from textmodel import TextModel\r\n >>> text = TextModel(u'Hello World')\r\n >>> text2 = TextModel(u'!', fontsize=20)\r\n >>> text.insert(11, text2)\r\n >>> text.set_properties(6, 11, bgcolor='yellow')\r\n >>> for i in range(1000):\r\n ... text.append(TextModel(\"Line %i\\n\" % i))\r\n >>> text.linelength(0) # length of first line\r\n 19\r\n >>> text.index2position(100) # row, col of index 100\r\n (12, 2)\r\n\r\n\r\nIntroduction\r\n------------\r\n\r\nWord processors are usually believed to be heavy and slow\r\napplications. However I think, that it is possible to design a word\r\nprocessor which is light weight and which is fast - so fast that it\r\neven can be implemented in a \"slow\" scripting language. Text model is\r\nment to be a prove of concept (even though it is merely a text editor\r\nand not a full word processor).\r\n\r\nStoring and editing text information is a problem with a long history\r\nin computer science. Known solutions include the `gap buffer\r\n`_ (used by Emacs), the\r\n`piece table `_ (used\r\nby MS-Word) and the `rope data structure\r\n`_ . Instead,\r\ntext model uses internally a structure which I named \"texel tree\" and\r\nwhich is probably a new approach to the problem. The goal was to find\r\na data structure which stores text together with format information\r\nand is\r\n\r\n- fast (even when implemented in a scripting language)\r\n- efficient (in memory consumption)\r\n- hierarchic (so that texts can contain elements like tables which\r\n itself contain text)\r\n\r\nThe texel tree consists of nodes which are called texels (text\r\nelements). Each texel can have a variable number of child texels\r\n(between 8 and 15), forming a highly branched tree, similar to a\r\nB-tree. Operations to the tree a performed in such a way, that the\r\ntree is kept balanced, i.e. all branches have exactly the same\r\ndepth. The texel tree is fast because it allows all text operations\r\n(insert, remove, copy, paste) in logarithmic time. It is efficient\r\nbecause it stores text on the level of strings and not on the\r\ncharacter level and it stores the styling in a economic way. \r\n\r\nText model is an interface to the texel tree, hiding all the\r\ncomplexity of the recursive texel data structure. It is termed \"text\r\nmodel\" because in a model-view-controller scenario it would have the\r\nrole of the \"model\". A matching view / editor component is\r\n`wxtextview `_. In\r\ncombination they can be used as text editor.\r\n\r\n\r\nSpeed\r\n-----\r\n\r\nNote that textmodel is not yet optimized. By saying that the texel\r\nstructure is fast, I mean that the time of operations grows only\r\nslowly with the length of the text. I would not be surprised, if the\r\ntimes could be improved by a factor of 2 or more.\r\n\r\nThe following table shows how the time needed to insert a line grows\r\nwith the length of the text. The text length is measured as number of\r\ntext nodes, where each text node holds one line of text, e.g. 50000\r\nmeans a text with 50 thousand lines of text.\r\n\r\n=============== ====================\r\n # lines time (milliseconds)\r\n=============== ====================\r\n 1 0.332514\r\n 3 0.379985\r\n 5 0.436915\r\n 10 0.519033\r\n 30 0.596213\r\n 50 0.657198\r\n 100 0.75822\r\n 300 0.843198\r\n 500 0.897312\r\n 1000 0.998324\r\n 3000 1.081806\r\n 5000 1.136462\r\n 10000 1.246638\r\n 30000 1.356982\r\n 50000 1.404089\r\n=============== ====================\r\n\r\nAs can be seen, the time grows only very little with number of\r\nlines. Ideally, I would expect a logarithmic dependence on text\r\nlength. This is especially true for the following operations:\r\n\r\n- inserting strings\r\n- inserting other trees (=paste)\r\n- copying text\r\n- removing text\r\n- calculating index positions from (row, col)-tuples and vice versa\r\n- counting lines\r\n\r\nMoreover, pasting and cutting text changes only little with the size of\r\nthe text which is cut out or pasted in. Again, there should be a\r\nlogarithmic dependence.\r\n\r\nImplementation details\r\n----------------------\r\n\r\nThe texel tree consists of different kinds of texels: group texels,\r\ncharacter texels, glyphs texels and containers texels.\r\n\r\nCharacter texels hold strings of uniformly styled unicode\r\ntext. NewLines are a special case of character texels. Groups hold\r\nchild elements. The following texel stores the words *Hello world!*\r\nwith *world* marked with red.\r\n\r\n::\r\n\r\n G[C('Hello'), C('world!', bgcolor='red')] \r\n \r\nEach texel has a length, which corresponds to the number of contained\r\ncharacters. For example, the length of C('Hello') is 5 and the length\r\nof an empty group is zero.\r\n\r\nThere are also texels for new lines and tabs and a special mark for\r\nthe end of text.\r\n\r\nIt is easy to extend text model by introducing new texels, e.g. tables\r\nand math formulas.\r\n\r\nEach texel has a **weights** attribute. This attribute is one of the\r\nreasons for the high efficiency of the texel tree. It is a tuple of 3\r\ninteger numbers and it facilitates fast navigation in the tree. The\r\nfirst entry gives the depth of the texel, which is needed internally,\r\nthe second gives the number of characters in texel and the third gives\r\nthe number of line breaks in the texel. The latter is used excessively\r\nby methods as nlines, linelength, lineend and index2position.", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://pypi.python.org/pypi/textmodel/", "keywords": null, "license": "BSD", "maintainer": null, "maintainer_email": null, "name": "textmodel", "package_url": "https://pypi.org/project/textmodel/", "platform": "any", "project_url": "https://pypi.org/project/textmodel/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://pypi.python.org/pypi/textmodel/" }, "release_url": "https://pypi.org/project/textmodel/0.3.6/", "requires_dist": null, "requires_python": null, "summary": "A data type for storing and manipulating rich text data. It aims to be fast and efficient and it is suited even for very long texts.", "version": "0.3.6" }, "last_serial": 1942226, "releases": { "0.0": [ { "comment_text": "built for CYGWIN_NT-6.1-WOW64-1.7.20-0.266-5-3", "digests": { "md5": "7950de4f72ae3357800c9df2bb9f8650", "sha256": "2ae3c3baa14bb9222a7ba737ca593095af9f06cbc6b01b8ee19386c436082fbe" }, "downloads": -1, "filename": "textmodel-0.0.cygwin-1.7.20-i686.tar.gz", "has_sig": false, "md5_digest": "7950de4f72ae3357800c9df2bb9f8650", "packagetype": "bdist_dumb", "python_version": "any", "requires_python": null, "size": 62712, "upload_time": "2013-06-30T19:33:01", "url": "https://files.pythonhosted.org/packages/76/a2/3f6dc875c8ea602851392b5147c60e2cab9ff68ede3125ac5dc622c28a8b/textmodel-0.0.cygwin-1.7.20-i686.tar.gz" }, { "comment_text": "", "digests": { "md5": "7a41199a8dc99d8751ff86e9ae5d221e", "sha256": "b9d03f6228f10b48ee0214abe6f1d4b7ed2a322875f50ededaf8b7a2d5ce07e5" }, "downloads": -1, "filename": "textmodel-0.0.tar.gz", "has_sig": false, "md5_digest": "7a41199a8dc99d8751ff86e9ae5d221e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26142, "upload_time": "2013-06-30T19:32:54", "url": "https://files.pythonhosted.org/packages/1c/b5/cafa4f95693fc3b10a7fe44fdd8d77a4f0eaf750a450ebd5edbf357c4a74/textmodel-0.0.tar.gz" } ], "0.1": [ { "comment_text": "", "digests": { "md5": "b72079e88ce3c4eb4a8bb1b7d145ab4e", "sha256": "d03cea5250871419ecf2d1b58b9bb7448cdd3ed781d17e1d73d22a51c3068317" }, "downloads": -1, "filename": "textmodel-0.1.zip", "has_sig": false, "md5_digest": "b72079e88ce3c4eb4a8bb1b7d145ab4e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 31996, "upload_time": "2013-08-14T18:56:02", "url": "https://files.pythonhosted.org/packages/6d/0c/92393b4d887ed66f23c83c9731533efc4b4c8e49b5cfc6abf482a18523b5/textmodel-0.1.zip" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "ff11bba6de7597042226ddc5d2a9a4fc", "sha256": "d98c5e8633141fffe9dd6e4ade08f8a06ac633dc2f07c2d44dcd446aa819ee19" }, "downloads": -1, "filename": "textmodel-0.1.1.zip", "has_sig": false, "md5_digest": "ff11bba6de7597042226ddc5d2a9a4fc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 36732, "upload_time": "2013-08-14T19:06:27", "url": "https://files.pythonhosted.org/packages/fa/77/cc6f044812c4af6b275e92fc7c6919ff2b25571458821fca14f8ce435e62/textmodel-0.1.1.zip" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "4a0d2510f8fe4cf6575f7188a6b1c88d", "sha256": "bffeefadbd599ebc2a49b332ff29c07365271421086d54f9416391d750f38b13" }, "downloads": -1, "filename": "textmodel-0.2.tar.gz", "has_sig": false, "md5_digest": "4a0d2510f8fe4cf6575f7188a6b1c88d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 43667, "upload_time": "2014-01-03T17:41:10", "url": "https://files.pythonhosted.org/packages/9d/83/7e653e930a4b07501f519108d24eaf5c9fa70eb4a9addc2445412f5f3cce/textmodel-0.2.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "db1f9d1b32669fa750516141d744f908", "sha256": "a672cce7e7f3bc8a08144ee2f689ac059e707cac3079ced289c4180d568b576a" }, "downloads": -1, "filename": "textmodel-0.2.1.zip", "has_sig": false, "md5_digest": "db1f9d1b32669fa750516141d744f908", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 54599, "upload_time": "2014-01-06T21:40:10", "url": "https://files.pythonhosted.org/packages/0d/f0/8ecbbe7e20f4ba511f87299c688a87a52447daaa408902643d8f4e5bbcfd/textmodel-0.2.1.zip" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "b49f2c870caa4ab14e039d3a5f36b26e", "sha256": "008c5e91a2dd979485a9012088ff9a7e595550c9cd110e54a58f4fb8e4a1b010" }, "downloads": -1, "filename": "textmodel-0.2.2.zip", "has_sig": false, "md5_digest": "b49f2c870caa4ab14e039d3a5f36b26e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 54435, "upload_time": "2014-01-07T20:49:41", "url": "https://files.pythonhosted.org/packages/89/bb/e1772c3051267e74c515ce60884d6d8cfb27b3d3b47f69beddfc58412fb2/textmodel-0.2.2.zip" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "c6134fdf2345bf891152e6927e0f3e03", "sha256": "915a6163dd38a3c4332ef3150e8b534e4358f8156c00652a1d0ac8dfb0ce7cef" }, "downloads": -1, "filename": "textmodel-0.3.tar.gz", "has_sig": false, "md5_digest": "c6134fdf2345bf891152e6927e0f3e03", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 49895, "upload_time": "2015-04-13T21:23:13", "url": "https://files.pythonhosted.org/packages/98/41/e02eb7a1c8cd7b91a6c7a0dcde6d6628024390052a55c7993fe82b0bb521/textmodel-0.3.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "93417b00936fb355a2f249307bf4e966", "sha256": "c0b906e7e3c0d0dc14da47c1706b69214bc84e8de8a7426998a09be62fff6359" }, "downloads": -1, "filename": "textmodel-0.3.1.tar.gz", "has_sig": false, "md5_digest": "93417b00936fb355a2f249307bf4e966", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 49844, "upload_time": "2015-04-15T18:20:06", "url": "https://files.pythonhosted.org/packages/a7/02/f444cb6a870e67c78230c9d6895ce66c0d050a17dfbaf8485a4da1a5081d/textmodel-0.3.1.tar.gz" } ], "0.3.2": [ { "comment_text": "", "digests": { "md5": "fdb927c654b07c0dacf53854d46445f3", "sha256": "6c5600b510058573381c8eaa4639559439695a9e036f2c58a5003f2a3b0feecf" }, "downloads": -1, "filename": "textmodel-0.3.2.tar.gz", "has_sig": false, "md5_digest": "fdb927c654b07c0dacf53854d46445f3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25001, "upload_time": "2015-05-12T20:15:04", "url": "https://files.pythonhosted.org/packages/17/b4/c8044ade807822d632915b1fc2774b9a4b0199d7342e0fe9691ade6e5439/textmodel-0.3.2.tar.gz" } ], "0.3.3": [ { "comment_text": "", "digests": { "md5": "bb7f9ff92ef3804a8f69baf3c355f080", "sha256": "ce9574331160bee41b1ba6eb1b1404b6d7f847772f8847668bb4ea091cee476e" }, "downloads": -1, "filename": "textmodel-0.3.3.tar.gz", "has_sig": false, "md5_digest": "bb7f9ff92ef3804a8f69baf3c355f080", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25687, "upload_time": "2015-06-20T17:32:49", "url": "https://files.pythonhosted.org/packages/78/e8/04c1f2e23e434aca330651c41fe7f4fdfa69a00063e89c31ce3ecc454dfb/textmodel-0.3.3.tar.gz" } ], "0.3.4": [ { "comment_text": "", "digests": { "md5": "291afbf798c10a6b93b71fa967a8c8dd", "sha256": "7a61ae5ea42f6ff37a7389a112b5071a437e636cc241e2399b0f25aec037e949" }, "downloads": -1, "filename": "textmodel-0.3.4.tar.gz", "has_sig": false, "md5_digest": "291afbf798c10a6b93b71fa967a8c8dd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26118, "upload_time": "2015-06-22T17:52:34", "url": "https://files.pythonhosted.org/packages/e9/6c/9c473c09efecef9fa08cd3647fc3e2444536a42e18e743058470b70ff9c1/textmodel-0.3.4.tar.gz" } ], "0.3.5": [ { "comment_text": "", "digests": { "md5": "daa1733f3875cea3b9746237538c452b", "sha256": "a0347629ebe7bd8bd6b423bf904f5facb50e78037ab951c528959b15e1114d86" }, "downloads": -1, "filename": "textmodel-0.3.5.tar.gz", "has_sig": false, "md5_digest": "daa1733f3875cea3b9746237538c452b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26362, "upload_time": "2015-12-05T18:24:32", "url": "https://files.pythonhosted.org/packages/2f/b2/9e43790232b4f326a7d100d1614a8e8d96ab74b7d16239a1de321f7127f8/textmodel-0.3.5.tar.gz" } ], "0.3.6": [ { "comment_text": "", "digests": { "md5": "d4791324b7a046936c49080aae0d906b", "sha256": "6735b01d178199ea096382302faddd9170c0cb297401172ee7f9811214f6d985" }, "downloads": -1, "filename": "textmodel-0.3.6.tar.gz", "has_sig": false, "md5_digest": "d4791324b7a046936c49080aae0d906b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27026, "upload_time": "2016-02-05T20:45:38", "url": "https://files.pythonhosted.org/packages/a1/e5/8a47272b156872eece411e80bef462d152d9170c025f2786d7017fda783e/textmodel-0.3.6.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d4791324b7a046936c49080aae0d906b", "sha256": "6735b01d178199ea096382302faddd9170c0cb297401172ee7f9811214f6d985" }, "downloads": -1, "filename": "textmodel-0.3.6.tar.gz", "has_sig": false, "md5_digest": "d4791324b7a046936c49080aae0d906b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27026, "upload_time": "2016-02-05T20:45:38", "url": "https://files.pythonhosted.org/packages/a1/e5/8a47272b156872eece411e80bef462d152d9170c025f2786d7017fda783e/textmodel-0.3.6.tar.gz" } ] }