SERVER_HOST = '127.0.0.1'
 PATH_TEMPLATES = Path('templates')
 
+PREFIX_DEF = 'def '
 PREFIX_LEDGER = 'ledger_'
 PREFIX_EDIT = 'edit_'
 PREFIX_FILE = 'file_'
 class Account:
     """Combine name, position in tree of own, and wealth of self + children."""
 
-    def __init__(self, parent: Optional['Account'], basename: str) -> None:
+    def __init__(self, parent: Optional['Account'], basename: str, desc: str
+                 ) -> None:
         self.local_wealth = Wealth()
         self.basename = basename
+        self.desc = desc
         self.children: list[Self] = []
         self.parent = parent
         if self.parent:
             total += child.wealth
         return total
 
-    @staticmethod
-    def by_paths(acc_names: list[str]) -> dict[str, 'Account']:
-        """From bookings generate dict of all refered Accounts by paths."""
-        paths_to_accs: dict[str, Account] = {}
-        for full_name in acc_names:
-            path = ''
-            for step_name in full_name.split(':'):
-                parent_name = path[:]
-                path = ':'.join([path, step_name]) if path else step_name
-                if path not in paths_to_accs:
-                    paths_to_accs[path] = Account(
-                        paths_to_accs[parent_name] if parent_name else None,
-                        step_name)
-        return paths_to_accs
-
-    @staticmethod
-    def names_over_bookings(bookings: list['Booking']) -> list[str]:
-        """Sorted list of all account names refered to in bookings."""
-        names = set()
-        for booking in bookings:
-            for account_name in booking.account_changes:
-                names.add(account_name)
-        return sorted(list(names))
-
 
 class DatLine(Dictable):
     """Line of .dat file parsed into comments and machine-readable data."""
         to_balance = (self.server.bookings[:id_ + 1] if id_ >= 0
                       else self.server.bookings)
         valid = 0 == len([b for b in to_balance if b.is_questionable])
-        acc_dict = Account.by_paths(Account.names_over_bookings(to_balance))
+        acc_dict = self.server.empty_accounts_by_path(id_)
         for booking in to_balance:
             booking.apply_to_account_dict(acc_dict)
         ctx['roots'] = [ac for ac in acc_dict.values() if not ac.parent]
         """Display edit form for individual Booking."""
         id_ = int(self.path_toks[2])
         booking = self.server.bookings[id_]
-        acc_names = Account.names_over_bookings(self.server.bookings)
         to_balance = self.server.bookings[:id_ + 1]
-        accounts_after = Account.by_paths(acc_names)
-        accounts_before = Account.by_paths(acc_names)
+        accounts_after = self.server.empty_accounts_by_path()
+        accounts_before = self.server.empty_accounts_by_path()
         for b in to_balance:
             if b != booking:
                 b.apply_to_account_dict(accounts_before)
         ctx['valid'] = 0 == len([b for b in to_balance if b.is_questionable])
         ctx['roots'] = observed_tree
         if not raw:
-            ctx['all_accounts'] = acc_names
+            ctx['all_accounts'] = accounts_after.keys()
         self._send_rendered(EDIT_RAW if raw else EDIT_STRUCT, ctx)
 
     def get_ledger(self, ctx: dict[str, Any], raw: bool) -> None:
                     self.bookings += [booking]
                     booked_lines.clear()
                 gap_lines += [dat_line]
+        self.paths_to_descs = {}
+        for comment in [dl.comment for dl in self.dat_lines if dl.comment]:
+            if comment.startswith(PREFIX_DEF):
+                parts = [part.strip() for part
+                         in comment[len(PREFIX_DEF):].split(';')]
+                first_part_parts = parts[0].split(maxsplit=1)
+                account_name = first_part_parts[0]
+                desc = first_part_parts[1] if len(first_part_parts) > 1 else ''
+                if desc:
+                    self.paths_to_descs[account_name] = desc
         for booking in self.bookings:
             booking.recalc_prev_next(self.bookings)
         if booking:
     def _hash_dat_lines(self) -> int:
         return hash(tuple(dl.raw for dl in self.dat_lines))
 
+    def empty_accounts_by_path(self,
+                               up_incl: int = -1
+                               ) -> dict[str, 'Account']:
+        """Dict of Accounts refered in .bookings till up_incl by paths."""
+        booked_names = set()
+        for booking in (self.bookings[:up_incl + 1] if up_incl >= 0
+                        else self.bookings):
+            for account_name in booking.account_changes:
+                booked_names.add(account_name)
+        paths_to_accs: dict[str, Account] = {}
+        for full_name in booked_names:
+            path = ''
+            for step_name in full_name.split(':'):
+                parent_name = path[:]
+                path = ':'.join([path, step_name]) if path else step_name
+                if path not in paths_to_accs:
+                    paths_to_accs[path] = Account(
+                        paths_to_accs[parent_name] if parent_name else None,
+                        step_name,
+                        self.paths_to_descs.get(path, ''))
+        return paths_to_accs
+
     @property
     def tainted(self) -> bool:
         """If .dat_lines different to those of last .load()."""