{"id":14980873,"url":"https://github.com/k1dv5/docal","last_synced_at":"2025-08-16T12:33:30.634Z","repository":{"id":57423171,"uuid":"137065913","full_name":"K1DV5/docal","owner":"K1DV5","description":"Do calculations and automatically insert them into your document","archived":false,"fork":false,"pushed_at":"2024-06-16T09:06:57.000Z","size":467,"stargazers_count":46,"open_issues_count":0,"forks_count":5,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-12-15T16:55:43.946Z","etag":null,"topics":["calculations","engineering","equation","latex","latex-document","mathcad","python","python-library","scientific-reports"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/K1DV5.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-06-12T12:06:12.000Z","updated_at":"2024-10-29T02:40:36.000Z","dependencies_parsed_at":"2024-09-28T05:00:50.698Z","dependency_job_id":"92133d7c-b5a8-4ac1-b1c7-f50dc4dd7497","html_url":"https://github.com/K1DV5/docal","commit_stats":{"total_commits":359,"total_committers":3,"mean_commits":"119.66666666666667","dds":0.0696378830083565,"last_synced_commit":"12d22a9b344243c231497bb62be57a9ae7ab787f"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/K1DV5%2Fdocal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/K1DV5%2Fdocal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/K1DV5%2Fdocal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/K1DV5%2Fdocal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/K1DV5","download_url":"https://codeload.github.com/K1DV5/docal/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230038878,"owners_count":18163311,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["calculations","engineering","equation","latex","latex-document","mathcad","python","python-library","scientific-reports"],"created_at":"2024-09-24T14:02:31.931Z","updated_at":"2025-08-16T12:33:30.621Z","avatar_url":"https://github.com/K1DV5.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# docal\n\n[![image](https://img.shields.io/pypi/v/docal.svg)](https://pypi.python.org/pypi/docal)\n\nInject Python calculations into Word and LaTeX documents with ease!\n\n- Free software: MIT license\n\ndocal is a tool that can be used to send calculations that are written in\npython to Word or LaTeX documents. It evaluates equations in a separate python\nscript from the document and replaces hashtags in the document that indicate\nwhere the calculations should be with the results of the evaluation. It comes\nwith a powerful python expression to document equations converter built-in, so\nit converts the calculations and their results into their native equation forms\nof the document before sending them, which makes it ideal to make academic and\nscientific reports.\n\n## Installation\n\n### Requirements\n\nThe only requirement is Python with [this\nversion](https://github.com/K1DV5/docal/blob/e00bde00b67ef672816abc381ad1c36325137159/pyproject.toml#L14),\nand with `pip`.\n\n### Install\n\nTo install this package, type the following command and hit Enter.\n\n```shell\npip install docal\n```\n\nOr from the source:\n\n```shell\npip install .\n```\n\nTo install the LSP support (see below), you can add `[lsp]`:\n```shell\npip install docal[lsp]\n```\n\n## Usage\n\nThe typical workflow is as follows:\n\n- The static parts of the document are written as usual (Word or\n  LaTeX) but leaving sort of unique hashtags (\\#tagname) for the\n  calculation parts.\n\n- The calculations are written on a separate text file with any text\n  editor and saved next to the document file. For the syntax of the calculation\n  file, see below. But it\\'s just a python script with comments.\n\n- The tool is invoked with the following command:\n\n  ```shell\n  docal [calculation-file] -i [input-file] -o [output-file]\n  ```\n\n  so for example,\n\n  ```shell\n  docal calcs.py -i document.tex -o document-out.tex\n  ```\n- Then voila! what is needed is done. The output file can be used\n  normally.\n\n## Example\n\nLet\\'s say you have a word document `foo.docx` with contents like this.\n\n![Word document input](https://raw.githubusercontent.com/K1DV5/docal/master/images/word-in.png)\n\nAnd you write the calculations in the file `foo.py` next to `foo.docx`\n```python\n## foo.py\n## necessary for scientific functions:\nfrom math import *\n\n#foo\n\n# The first side of the first triangle is\nx_1 = 5 #m\n# and the second,\ny_1 = 6 #m\n# Therefore the length of the hypotenuse will be,\nz_1 = sqrt(x_1**2 + y_1**2) #m\n\n#bar\n\n# Now the second triangle has sides that have lengths of\nx_2 = 3\ny_2 = 4\n# and therefore has a hypotenuse of\nz_2 = sqrt(x_2**2 + y_2**2) #m,13\n\n# Then, we can say that the hypotenuse of the first triangle which is #z_1 long\n# is longer than that of the second which is #z_2 long.\n```\n\nNow, If we run the command \n\n```shell\ndocal foo.py -o foo.docx\n```\n\nA third file, named `foo-out.docx` will appear. And it will look like this:\n\n![Word document output](https://raw.githubusercontent.com/K1DV5/docal/master/images/word-out.png)\n\n## Syntax\n\nThe syntax is simple. Just write the equations one line at a time. What\nyou write in the syntax is a valid Python file, (it is just a script\nwith a lot of assignments and comments).\n\n### Equations (python assignments)\n\nThese are the main focus points of this module. Obviously, they are\nevaluated as normal in the script so that the value of the variable can\nbe reused as always, but when they appear in the document, they are\ndisplayed as equation blocks that can have up to three steps (that show\nthe procedures).\n- If it is a simple assignment, like `x = 10`, they appear only having a single step, because there is no procedure to show.\n- If the assignment contains something to be evaluated but no variable reference like `x = 10 + 5 / 2` or if it contains a single variable reference like `x = x_prime` then the procedure will have only two steps, first the equation and second the results.\n- If the equation has both things to be evaluated and variable references, like\n`x = 5*x_prime + 10` then it will have three steps: the equation itself, the equation with variable references substituted by their values, and the result.\n\nThese equations can be customized using comments at their ends (see below).\n\n### Comments after equations (options)\n\nThese comments are taken to be customization options for the equations.\nMultiple options can be separated by commas.\n\n- **Units**: If you write something that looks like a unit (names or expressions of names) like `N/m**2` they are correctly displayed as units next to the result and whenever that variable is referenced, next to its value. Note that this is just showing units. Otherwise, units are not involved in computations.\n- **Display type**:\n    - If the option is a single dollar sign `$`, the equation will be inline and if it has more than a single step, the steps appear next to each other.\n    - If it is double dollar signs `$$`, the equation(s) will be displayed as block (centered) equations (default).\n- **Step overrides**: If it is a sequence of digits like `12`, then only the steps corresponding to that number will be displayed (for this case steps 1 and 2).\n- **Matrix and array cut-off size**: Matrices are cut off and displayed with dots in them if their sizes are greater than this and arrays are cut off if they have more than this number. To override this number, the option is the letter m followed by a number like `m6`. Default: `m10`\n- **Note**: If the option starts with a hash sign like `#this is a note`, what follows will be a little note that will be displayed next to the last step.\n- **Omit**: If the option is `;` then it means omit this line in the document.\n- **Override result**: If the option starts with an equal sign like `=34` then the value after the equal sign will be written in the document as the final answer.\n- **Decimal points**: If the option starts with the letter d like `d2` then the number will specify the maximum number of digits after the decimal point. Default: `d3`\n- **Force vertical**: You can force the steps to go vertically (as block equations) using `|` or horizontally (as inline equations) using `-`.\n\n### Comments that take whole lines\n\nThese comments are converted to paragraphs or equations, depending on\nwhat comes immediately after the hash sign.\n\n- If the line starts with `#@` then the rest of the line is interpreted as options for subsequent assignments. See above about the options.\n- Equations:\n    - If the hash sign is followed by a single dollar sign (`$`), the rest of that line is expected to be a python equation, and will be converted to an inline LaTeX equation.\n    - If what comes after the dollar sign is two dollar signs (`$$`), the rest of that line will be converted to a displayed (block) equation in the document.\n- Running text: If the hash sign is followed by just running text, it is converted to a paragraph text.\n\nIn the last two cases, when a hash character immediately followed by a variable\nname like `#x`, the value of that variable will be substituted at that place.\nWhen a hash character immediately followed by an expression surrounded by\nsquirrely braces like `#{x + 2}` is encountered, what is inside the braces will\nbe evaluated and substituted at that place.\n\n### Comments that begin with double hash signs\n\nIf you begin a comment line with double hash signs, like `## comment` it\nis taken as a real comment. It will not do anything.\n\n### Other code\n\nOther code elements like import statements, loops, function definitions, etc.\nare just executed and will not be included in the document.\n\n### Variable names\n\nThe names of variables are transformed into a sensible mathematical notation in the following ways:\n\nThe variable can be made of parts joined by underscores (or a single part\nwithout any) and the parts decide how the variable will be rendered in the\ndocument.\n\n- For any part of the variable,\n    - If it is a greek letter name, like `alpha`, it is rendered as the actual greek letter. To write capital Greek letters, start the variable name with a capital like `Alpha`.\n    - If the name is a single letter like `x` then it is rendered as an italic single letter.\n    - If is more than one character, it is rendered as text, with upright characters.\n- If the variable contains two parts with a single underscore, like `x_y`:\n    - If the second part is the name of an accent or a prime listed in the following, like `x_hat`, it modifies the first part.\n        - `hat`\n        - `check`\n        - `breve`\n        - `acute`\n        - `grave`\n        - `tilde`\n        - `bar`\n        - `vec`\n        - `dot`\n        - `ddot`\n        - `dddot`\n        - `prime`\n        - `2prime`\n        - `3prime`\n- If it contains two parts with double underscore, like `x__y`, the second part `y` becomes a superscript.\n\nIt is possible to combine the above into a name like `alpha_bar_foo__x`.\n\n### Transformations\n\nThe following things are transformed into their mathematical notations:\n\n- `sqrt()`: into the square root symbol as shown in the example\n- `degC` and `degF`: into the degree Celsius or degree Fahrenheit symbols\n- `deg`: the degree symbol for angles for example\n- `integral()`: the integral sign from calculus\n- Instances of `numpy.matrix` and 2D lists: into the matrix notation\n- Instances of `numpy.array` and 1D lists: into the vector notation\n\n### Fill tables from variables (Word only)\n\nTables can be filled from 2D variables (lists of lists or numpy matrices). To\ndo that, all that's required is to create a template table and place the name\nof the variable as a \\#hashtag inside the cell where we want the table to be\nfilled from. Then it starts filling the table from that cell to the right and\ndown. If there are no columns or rows left, new ones will be added, so that we\ndon't have to know the size of the final table beforehand.\n\n## LSP support\n\nThere is LSP mode for basic assistance which evaluates and shows the\nvalues of the variables as inlay hints which can be used to get immediate\nfeedback on our calculations. On Neovim, it looks like this:\n\n![LSP Info](https://raw.githubusercontent.com/K1DV5/docal/master/images/lsp.png)\n\nTo not clutter the screen, it doesn't show values for simple assignments of\nconstants, and it doesn't repeat the name of the variable when there is only\none.\n\nIt can be started as\n\n```shell\ndocal --lsp\n```\n\nIt only watches files whose name matches the pattern `*.docal.py` Right now, it\nhas been tested with the following editors.\n\n### Neovim\n\nUsing the built-in config of Neovim v0.11, it is very easy to configure. The\nfollowing is an example config to use it:\n\n```lua\nvim.lsp.config.docal = {\n  cmd = { 'docal', '--lsp' },\n  filetypes = { 'python' },\n}\n\nvim.lsp.enable({'docal'})\n-- inlay hints have to be enabled as well\nvim.lsp.inlay_hint.enable()\n```\n\n### VSCode\n\nThere is no custom made extension for this, but it is faily easy to use a\ngeneric LSP client extension like [this](https://github.com/zsol/vscode-glspc)\nand make it work with it. For example, for the mentioned extension, the only\nnecessary settings are:\n\n- `glspc.server.command`: `docal`\n- `glspc.server.commandArguments`: Add one: `--lsp`\n- `glspc.server.languageId`: `python`\n\nNote that when the editor is started, `docal` has to be already instealled and\navailable in `$PATH`. [Read\nmore](https://github.com/zsol/vscode-glspc#failed-to-start-server-spawn-command-enoent)\n\n## Notes\n\n**Security**: `eval() and exec()` are used to get the actual values. In most\ncases this should not be a problem as you are writing your own calculation\nscripts which you want to run anyway. But still, I'm not an expert on the\npossible security implications though you should make sure that imported code\nis from a trusted source.\n\nPython's AST changes almost every release. And since this package depends on\nthat, supporting every new version of python will be like a moving target. This\nproject has been developed against the Python versions available at the time of\nwriting. There was the option of using\n[ast-compat](https://pypi.org/project/ast-compat/) to not be affected by the\nchanging AST, but I'm not sure if introducing a dependency is worth the\nbenefits. Therefore, my current approach is to update the code and release\nmajor versions when there are changes to the AST that affect this package.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fk1dv5%2Fdocal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fk1dv5%2Fdocal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fk1dv5%2Fdocal/lists"}