{"id":21020947,"url":"https://github.com/awto/pretty-template","last_synced_at":"2026-04-29T06:31:52.688Z","repository":{"id":4785076,"uuid":"5937332","full_name":"awto/pretty-template","owner":"awto","description":"prototype implementation of template system fused with pretty printer","archived":false,"fork":false,"pushed_at":"2015-04-19T20:00:46.000Z","size":136,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-01-02T15:19:33.315Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/awto.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-09-24T16:28:26.000Z","updated_at":"2015-04-19T20:00:46.000Z","dependencies_parsed_at":"2022-09-07T10:41:13.580Z","dependency_job_id":null,"html_url":"https://github.com/awto/pretty-template","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/awto/pretty-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awto%2Fpretty-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awto%2Fpretty-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awto%2Fpretty-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awto%2Fpretty-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/awto","download_url":"https://codeload.github.com/awto/pretty-template/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awto%2Fpretty-template/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32414413,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T06:29:02.080Z","status":"ssl_error","status_checked_at":"2026-04-29T06:29:00.631Z","response_time":110,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2024-11-19T10:44:06.569Z","updated_at":"2026-04-29T06:31:52.672Z","avatar_url":"https://github.com/awto.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"pretty-template\n===============\n\nThis is a prototype of yet another string tempting library. The key distinction \nfrom the other libraries is pretty printing options embedded into template's \nsyntax. At the present version the options are based on Wadler/Leijen\npretty-printing combinators library. Other systems typically doesn't consider \nlayout at all. So either users have to put extra white-spaces destroying \ntemplate's layout or ignore output layout issues at all. It may be considered \nnot significant if resulting text is not supposed to be read by human (i.e. \nHTML or LaTeX) or there is some cheap alternatives for beautifying output \nformat. However there is quite large space for template's applications where text \nlayout does matter. A typical one is generation various kind of text reports, \nlikely based on localized strings. In case of code generation well layout output \nhelps debugging templates. In some programming languages text layout changes \nsemantics.\n \nFor example let's take a Java class generator task. In current syntax it looks \nlike:\n\n        package com.example.TestPackage;\n\n        ${imports */vcat $[import ${%$}.*;$]$}\n\n        public class ${name$} ${parent $[extends ${%$}$]$} {\n                ${members */?{\n                        field : $[${visibility$} ${ty$} ${name/\u003e\u003e $};$] ,\n                        method:$[${visibility$} ${result$} ${name$}(${args *$[${ty$} ${name$}$]$}) {\n                                  ${body$}\n                             }$]\n                        }\n               $}\n        }\n\n\nInput values may look like:\n\n       test1 :: ClassDef\n       test1 = ClassDef {\n          imports = [\"java.com\",\"java.class\"],\n          name = \"TestClass\",\n          parent = Just \"TestParent\",\n          members = [\n           Field {\n             mVisibility = Private,\n             mTy = \"int\",\n             mName = \"myvar\"\n           },\n           Method {\n             mVisibility = Public,\n             mResult = \"int\",\n             mName = \"getMyVar\",\n             mArgs = [],\n             mBody = \"return myvar;\"\n           },\n           Method {\n             mVisibility = Public,\n             mResult = \"void\",\n             mName = \"setMyVar\",\n             mArgs = [ArgDef \"int\" \"v\"],\n             mBody = \"myvar = v;\"\n           }\n          ]\n        }\n\nTemplates have two distinguished levels, namely template levels where template \nexpressions are specified and verbatim text level which is simply copied into \noutput. In code generation context the levels could be called meta-level and \nobject-level.\n\nHere \"${...$}\" parens switches from text-level to template-level and \"$[...$]\" back \nfrom template-level to text-level.\n\nAt the moment the library simply converts the template syntax into Wadler/Leijen \npretty-printing combinators application, though in some future version it is \nworth considering implementing some printing algorithm which is more specific \nfor string's template applications. The library also has implements simple \nheuristics for setting indent levels of each line.\n\nTemplate expressions for substitution of input data starts on name of field \nin the data after that a few other template expressions follow to handle that \nfield. If the field value is an atomic value it is just output to result. If \nit is another record a sub template is applied to the record. The sub-template \nis specified just after the field name. The scope of variable in that sub-template \nis within fields of the matched record. Optionally it is possible to set a template \nto apply in case if variable is not defined. It is next template expression which \nstarts with dot to be applied in this case.\n\nTo get a variable from parent record by means of \"^\" prefix. Current record can \nbe referred by means of % expression. \n\nFor list of values the variable name must be followed by \"*\" after which one \nrequired template expression and two optional may be specified. The required \nexpression is applied to each value in the list. Optional template expression, \nstarting on \",\" defines punctuation for the values and last argument started \non \".\" defines template for empty lists or not defined fields. \n\nThe way the templates are formatted can be controlled by means of options. \nThere are two groups of options. One may be applied only to list's template \nexpressions the other to over templates. List options are specified after the \nasterisk separated by \"/\". Options are just identifiers names which correspond \nto concatenation operators from the underlying pretty-printing library. By default \nit is \"hcat\". If no name is specified after \"/\" it is considered to be \"vsep\". \nOther supported values are \"hsep\", \"vsep\", \"feelsep\", \"lsep\", \"hcat\", \"vcat\", \n\"fillcat\", \"cat\".\n\nOptions which can be applied to any template expression are \"group\", \"hang\", \n\"nest\", \"align\". And there are a convenient aliases: \"\u003e\u003e\" for hang, \"\u003e\" for nest\", \n\"|\" for align, and \"-\" for not applying anything at all. By default it is always \nalign. Expression's options are defined in end of expression and separated by \"/\". \nIt has the lowest syntax priority so it binds to outer expression. Use parentheses \nto group template expressions and bind the options closely.\n\nRather typically an input of a template may be any structured data format like \nJSON or XML. Here aeson's JSON \"Value\" type is used as input data. In turn most\nof plain Haskell's types may be used via template haskell or generics.\n\nIn the templating system the tags are used for selecting sub-template to apply. \nThe tag is any string field of an object in parameter. By default it is \"tag\"\nfield.  It  simply matches the name of the tag to the name of corresponding \nsub-template. In  template syntax corresponding expression may be defined by c\nomma-separated pairs  of tag name and template expression to apply if \ncorresponding value is tagged with that name. The name and the template \nexpression are separated by colon and whole case expression is enclosed into \ncurly braces. In the example by means of case expression the system emits either \nfield or methods definitions.\n\nThe tag based selection is replacement of if-then-else expressions in template \nlanguage. The system doesn't allow arbitrary control operators to encourage \nseparation of templates from business logic. It is one of the main design \noptions considered in all tempting systems. Some of them allow arbitrary \nexpressions with functions and typical control operators. Others only allow \nfilling in expression holes without any facilities to specialize sub-template \naccording to input values. This solution is somewhere in the middle. It provides \nquite enough control over template selection and, I believe, it doesn't break \nthe wanted separation.\n\nTODO:\n\n* 2D pretty printing\n* Staging\n* Quasiquoter for embedding into Haskell code\n* Template's compilation \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawto%2Fpretty-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fawto%2Fpretty-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawto%2Fpretty-template/lists"}