mdlogbook 0.1.0

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 (90) hide show
  1. checksums.yaml +7 -0
  2. data/AGENTS.md +80 -0
  3. data/CHANGELOG.md +16 -0
  4. data/CLAUDE.md +5 -0
  5. data/CODE_OF_CONDUCT.md +10 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +99 -0
  8. data/Rakefile +21 -0
  9. data/docs/sample-logs/sample-2025-01.md +122 -0
  10. data/docs/sample-logs/sample-2025-02.md +123 -0
  11. data/docs/sample-logs/sample-2025-03.md +116 -0
  12. data/docs/sample-logs/sample-2025-04.md +128 -0
  13. data/docs/sample-logs/sample-2025-05.md +122 -0
  14. data/docs/sample-logs/sample-2025-06.md +113 -0
  15. data/docs/sample-logs/sample-2025-07.md +122 -0
  16. data/docs/sample-logs/sample-2025-08.md +94 -0
  17. data/docs/sample-logs/sample-2025-09.md +119 -0
  18. data/docs/sample-logs/sample-2025-10.md +123 -0
  19. data/docs/sample-logs/sample-2025-11.md +113 -0
  20. data/docs/sample-logs/sample-2025-12.md +121 -0
  21. data/docs/usage.md +778 -0
  22. data/exe/mlb +6 -0
  23. data/lib/mdlogbook/arg_parser.rb +372 -0
  24. data/lib/mdlogbook/brace_expander.rb +59 -0
  25. data/lib/mdlogbook/cli.rb +224 -0
  26. data/lib/mdlogbook/config.rb +247 -0
  27. data/lib/mdlogbook/date_filter.rb +22 -0
  28. data/lib/mdlogbook/editor_launcher.rb +90 -0
  29. data/lib/mdlogbook/env.rb +95 -0
  30. data/lib/mdlogbook/file_resolver.rb +43 -0
  31. data/lib/mdlogbook/formatter/anonymize.rb +75 -0
  32. data/lib/mdlogbook/formatter/anonymize_dict.rb +36 -0
  33. data/lib/mdlogbook/formatter/base.rb +138 -0
  34. data/lib/mdlogbook/formatter/calendar.rb +154 -0
  35. data/lib/mdlogbook/formatter/chart_series_builder.rb +57 -0
  36. data/lib/mdlogbook/formatter/extract.rb +41 -0
  37. data/lib/mdlogbook/formatter/grid.rb +256 -0
  38. data/lib/mdlogbook/formatter/heatmap.rb +142 -0
  39. data/lib/mdlogbook/formatter/line_chart.rb +156 -0
  40. data/lib/mdlogbook/formatter/simple.rb +42 -0
  41. data/lib/mdlogbook/option_def.rb +68 -0
  42. data/lib/mdlogbook/option_registry.rb +205 -0
  43. data/lib/mdlogbook/overlap_checker.rb +42 -0
  44. data/lib/mdlogbook/parser.rb +213 -0
  45. data/lib/mdlogbook/period_spec.rb +56 -0
  46. data/lib/mdlogbook/raw_extractor.rb +100 -0
  47. data/lib/mdlogbook/runner/base.rb +66 -0
  48. data/lib/mdlogbook/runner/editor_runner.rb +49 -0
  49. data/lib/mdlogbook/runner/extract_format_runner.rb +54 -0
  50. data/lib/mdlogbook/runner/standard_format_runner.rb +105 -0
  51. data/lib/mdlogbook/runner/visual_format_runner.rb +77 -0
  52. data/lib/mdlogbook/runner.rb +27 -0
  53. data/lib/mdlogbook/section_extractor.rb +140 -0
  54. data/lib/mdlogbook/version.rb +6 -0
  55. data/lib/mdlogbook/work_thresholds.rb +37 -0
  56. data/lib/mdlogbook.rb +41 -0
  57. data/sig/mdlogbook/arg_parser.rbs +54 -0
  58. data/sig/mdlogbook/brace_expander.rbs +4 -0
  59. data/sig/mdlogbook/cli.rbs +14 -0
  60. data/sig/mdlogbook/config.rbs +60 -0
  61. data/sig/mdlogbook/date_filter.rbs +4 -0
  62. data/sig/mdlogbook/editor_launcher.rbs +9 -0
  63. data/sig/mdlogbook/env.rbs +32 -0
  64. data/sig/mdlogbook/file_resolver.rbs +9 -0
  65. data/sig/mdlogbook/formatter/anonymize.rbs +4 -0
  66. data/sig/mdlogbook/formatter/anonymize_dict.rbs +4 -0
  67. data/sig/mdlogbook/formatter/base.rbs +15 -0
  68. data/sig/mdlogbook/formatter/calendar.rbs +4 -0
  69. data/sig/mdlogbook/formatter/chart_series_builder.rbs +9 -0
  70. data/sig/mdlogbook/formatter/extract.rbs +4 -0
  71. data/sig/mdlogbook/formatter/grid.rbs +8 -0
  72. data/sig/mdlogbook/formatter/heatmap.rbs +10 -0
  73. data/sig/mdlogbook/formatter/line_chart.rbs +7 -0
  74. data/sig/mdlogbook/formatter/simple.rbs +6 -0
  75. data/sig/mdlogbook/option_def.rbs +30 -0
  76. data/sig/mdlogbook/option_registry.rbs +18 -0
  77. data/sig/mdlogbook/overlap_checker.rbs +13 -0
  78. data/sig/mdlogbook/parser.rbs +32 -0
  79. data/sig/mdlogbook/period_spec.rbs +11 -0
  80. data/sig/mdlogbook/raw_extractor.rbs +15 -0
  81. data/sig/mdlogbook/runner/base.rbs +4 -0
  82. data/sig/mdlogbook/runner/editor_runner.rbs +5 -0
  83. data/sig/mdlogbook/runner/extract_format_runner.rbs +4 -0
  84. data/sig/mdlogbook/runner/standard_format_runner.rbs +4 -0
  85. data/sig/mdlogbook/runner/visual_format_runner.rbs +4 -0
  86. data/sig/mdlogbook/runner.rbs +4 -0
  87. data/sig/mdlogbook/section_extractor.rbs +24 -0
  88. data/sig/mdlogbook/work_thresholds.rbs +11 -0
  89. data/sig/mdlogbook.rbs +8 -0
  90. metadata +149 -0
@@ -0,0 +1,13 @@
1
+ # Detects overlapping time entries within a Parser::Result.
2
+ class Mdlogbook::OverlapChecker
3
+ class Overlap < Data
4
+ attr_reader date: Date
5
+ attr_reader entry_a: Mdlogbook::Parser::Entry
6
+ attr_reader entry_b: Mdlogbook::Parser::Entry
7
+
8
+ def initialize: (date: Date, entry_a: Mdlogbook::Parser::Entry, entry_b: Mdlogbook::Parser::Entry) -> void
9
+ end
10
+
11
+ def check: (Mdlogbook::Parser::Result) -> Array[OverlapChecker::Overlap]
12
+ def format_message: (OverlapChecker::Overlap) -> String
13
+ end
@@ -0,0 +1,32 @@
1
+ # Parses markdown logbook files into structured Result objects.
2
+ class Mdlogbook::Parser
3
+ # Immutable value object representing a single time entry.
4
+ class Entry < Data
5
+ attr_reader range_str: String
6
+ attr_reader time: Float
7
+ attr_reader job: String
8
+ attr_reader line_number: Integer?
9
+
10
+ def initialize: (range_str: String, time: Float, job: String, ?line_number: Integer?) -> void
11
+
12
+ def start_minutes: () -> Integer
13
+ def end_minutes: () -> Integer
14
+ end
15
+
16
+ # Accumulates parsed entries and warnings for a set of log files.
17
+ class Result
18
+ attr_reader warnings: Array[String]
19
+
20
+ def initialize: () -> void
21
+ def add_entry: (Date, Parser::Entry) -> void
22
+ def add_warning: (String) -> void
23
+ def dates: () -> Array[Date]
24
+ def entries_on: (Date) -> Array[Parser::Entry]
25
+ def each_date: () { (Date) -> void } -> void
26
+ def merge!: (Parser::Result) -> self
27
+ end
28
+
29
+ def initialize: (?regexp: Regexp?) -> void
30
+ def parse_file: (String) -> Parser::Result
31
+ def parse: (IO) -> Parser::Result
32
+ end
@@ -0,0 +1,11 @@
1
+ # Represents a contiguous date range to be processed.
2
+ class Mdlogbook::PeriodSpec
3
+ attr_reader start_date: Date
4
+ attr_reader end_date: Date
5
+
6
+ def initialize: (Date, Date, ?month_unit: bool, ?relative: bool) -> void
7
+ def self.month: (Integer, Integer, ?relative: bool) -> PeriodSpec
8
+ def month_unit?: () -> bool
9
+ def relative?: () -> bool
10
+ def months_covered: () -> Array[[Integer, Integer]]
11
+ end
@@ -0,0 +1,15 @@
1
+ # Extracts raw markdown lines from logbook files, grouped by date section.
2
+ class Mdlogbook::RawExtractor
3
+ class Result
4
+ def initialize: () -> void
5
+ def dates: () -> Array[Date]
6
+ def lines_on: (Date) -> Array[String]
7
+ def each_date: () { (Date, Array[String]) -> void } -> void
8
+ def empty?: () -> bool
9
+ def merge!: (RawExtractor::Result) -> self
10
+ def add_section: (Date, Array[String]) -> void
11
+ end
12
+
13
+ def extract_file: (String, Range[Date]) -> RawExtractor::Result
14
+ def extract: (IO, Range[Date]) -> RawExtractor::Result
15
+ end
@@ -0,0 +1,4 @@
1
+ # Base class for all Runner subclasses, providing shared spec parsing and file loading.
2
+ class Mdlogbook::Runner::Base
3
+ def initialize: (env: Mdlogbook::Env, file_resolver: Mdlogbook::FileResolver) -> void
4
+ end
@@ -0,0 +1,5 @@
1
+ # Launches the user's editor for the target log file.
2
+ # After the editor exits successfully, validates the file for warnings and overlaps.
3
+ class Mdlogbook::Runner::EditorRunner < Mdlogbook::Runner::Base
4
+ def run: () -> void
5
+ end
@@ -0,0 +1,4 @@
1
+ # Runs extraction modes (raw, grep).
2
+ class Mdlogbook::Runner::ExtractFormatRunner < Mdlogbook::Runner::Base
3
+ def run: () -> void
4
+ end
@@ -0,0 +1,4 @@
1
+ # Runs standard summary views (simple, calendar, anonymize, anonymize_dict).
2
+ class Mdlogbook::Runner::StandardFormatRunner < Mdlogbook::Runner::Base
3
+ def run: () -> void
4
+ end
@@ -0,0 +1,4 @@
1
+ # Runs visual output modes (line_chart, grid, heatmap).
2
+ class Mdlogbook::Runner::VisualFormatRunner < Mdlogbook::Runner::Base
3
+ def run: () -> void
4
+ end
@@ -0,0 +1,4 @@
1
+ # Dispatches to the appropriate Runner subclass based on the output format.
2
+ module Mdlogbook::Runner
3
+ def self.dispatch: (env: Mdlogbook::Env) -> void
4
+ end
@@ -0,0 +1,24 @@
1
+ # Extracts markdown sections whose level-2 or level-3 headings match a regexp.
2
+ class Mdlogbook::SectionExtractor
3
+ class Section < Data
4
+ attr_reader date: Date
5
+ attr_reader heading_level: Integer
6
+ attr_reader heading: String
7
+ attr_reader lines: Array[String]
8
+
9
+ def initialize: (date: Date, heading_level: Integer, heading: String, lines: Array[String]) -> void
10
+ end
11
+
12
+ class Result
13
+ attr_reader sections: Array[SectionExtractor::Section]
14
+
15
+ def initialize: () -> void
16
+ def add_section: (SectionExtractor::Section) -> void
17
+ def each_section: () { (SectionExtractor::Section) -> void } -> void
18
+ def empty?: () -> bool
19
+ def merge!: (SectionExtractor::Result) -> self
20
+ end
21
+
22
+ def extract_file: (String, Range[Date], regexp: Regexp) -> SectionExtractor::Result
23
+ def extract: (IO, Range[Date], regexp: Regexp) -> SectionExtractor::Result
24
+ end
@@ -0,0 +1,11 @@
1
+ # Holds working-time thresholds derived from monthly targets.
2
+ class Mdlogbook::WorkThresholds
3
+ attr_reader target_hours: Numeric?
4
+ attr_reader working_days_per_month: Numeric
5
+ attr_reader daily_target: Float?
6
+ attr_reader high_threshold: Float?
7
+ attr_reader low_threshold: Float?
8
+
9
+ def initialize: (target_hours: Numeric?, ?working_days_per_month: Numeric) -> void
10
+ def target_hours?: () -> bool
11
+ end
data/sig/mdlogbook.rbs ADDED
@@ -0,0 +1,8 @@
1
+ # Top-level namespace for the mdlogbook gem.
2
+ module Mdlogbook
3
+ VERSION: String
4
+
5
+ # Base error class for mdlogbook-specific exceptions.
6
+ class Error < StandardError
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mdlogbook
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - akira yamada
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: unicode_plot
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: 0.0.5
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: 0.0.5
26
+ description: mdlogbook (mlb) parses Markdown-formatted work logs and displays aggregated
27
+ work hours as a list or calendar view. Supports flexible period specifiers for month,
28
+ week, and day ranges.
29
+ email:
30
+ - akira@arika.org
31
+ executables:
32
+ - mlb
33
+ extensions: []
34
+ extra_rdoc_files: []
35
+ files:
36
+ - AGENTS.md
37
+ - CHANGELOG.md
38
+ - CLAUDE.md
39
+ - CODE_OF_CONDUCT.md
40
+ - LICENSE.txt
41
+ - README.md
42
+ - Rakefile
43
+ - docs/sample-logs/sample-2025-01.md
44
+ - docs/sample-logs/sample-2025-02.md
45
+ - docs/sample-logs/sample-2025-03.md
46
+ - docs/sample-logs/sample-2025-04.md
47
+ - docs/sample-logs/sample-2025-05.md
48
+ - docs/sample-logs/sample-2025-06.md
49
+ - docs/sample-logs/sample-2025-07.md
50
+ - docs/sample-logs/sample-2025-08.md
51
+ - docs/sample-logs/sample-2025-09.md
52
+ - docs/sample-logs/sample-2025-10.md
53
+ - docs/sample-logs/sample-2025-11.md
54
+ - docs/sample-logs/sample-2025-12.md
55
+ - docs/usage.md
56
+ - exe/mlb
57
+ - lib/mdlogbook.rb
58
+ - lib/mdlogbook/arg_parser.rb
59
+ - lib/mdlogbook/brace_expander.rb
60
+ - lib/mdlogbook/cli.rb
61
+ - lib/mdlogbook/config.rb
62
+ - lib/mdlogbook/date_filter.rb
63
+ - lib/mdlogbook/editor_launcher.rb
64
+ - lib/mdlogbook/env.rb
65
+ - lib/mdlogbook/file_resolver.rb
66
+ - lib/mdlogbook/formatter/anonymize.rb
67
+ - lib/mdlogbook/formatter/anonymize_dict.rb
68
+ - lib/mdlogbook/formatter/base.rb
69
+ - lib/mdlogbook/formatter/calendar.rb
70
+ - lib/mdlogbook/formatter/chart_series_builder.rb
71
+ - lib/mdlogbook/formatter/extract.rb
72
+ - lib/mdlogbook/formatter/grid.rb
73
+ - lib/mdlogbook/formatter/heatmap.rb
74
+ - lib/mdlogbook/formatter/line_chart.rb
75
+ - lib/mdlogbook/formatter/simple.rb
76
+ - lib/mdlogbook/option_def.rb
77
+ - lib/mdlogbook/option_registry.rb
78
+ - lib/mdlogbook/overlap_checker.rb
79
+ - lib/mdlogbook/parser.rb
80
+ - lib/mdlogbook/period_spec.rb
81
+ - lib/mdlogbook/raw_extractor.rb
82
+ - lib/mdlogbook/runner.rb
83
+ - lib/mdlogbook/runner/base.rb
84
+ - lib/mdlogbook/runner/editor_runner.rb
85
+ - lib/mdlogbook/runner/extract_format_runner.rb
86
+ - lib/mdlogbook/runner/standard_format_runner.rb
87
+ - lib/mdlogbook/runner/visual_format_runner.rb
88
+ - lib/mdlogbook/section_extractor.rb
89
+ - lib/mdlogbook/version.rb
90
+ - lib/mdlogbook/work_thresholds.rb
91
+ - sig/mdlogbook.rbs
92
+ - sig/mdlogbook/arg_parser.rbs
93
+ - sig/mdlogbook/brace_expander.rbs
94
+ - sig/mdlogbook/cli.rbs
95
+ - sig/mdlogbook/config.rbs
96
+ - sig/mdlogbook/date_filter.rbs
97
+ - sig/mdlogbook/editor_launcher.rbs
98
+ - sig/mdlogbook/env.rbs
99
+ - sig/mdlogbook/file_resolver.rbs
100
+ - sig/mdlogbook/formatter/anonymize.rbs
101
+ - sig/mdlogbook/formatter/anonymize_dict.rbs
102
+ - sig/mdlogbook/formatter/base.rbs
103
+ - sig/mdlogbook/formatter/calendar.rbs
104
+ - sig/mdlogbook/formatter/chart_series_builder.rbs
105
+ - sig/mdlogbook/formatter/extract.rbs
106
+ - sig/mdlogbook/formatter/grid.rbs
107
+ - sig/mdlogbook/formatter/heatmap.rbs
108
+ - sig/mdlogbook/formatter/line_chart.rbs
109
+ - sig/mdlogbook/formatter/simple.rbs
110
+ - sig/mdlogbook/option_def.rbs
111
+ - sig/mdlogbook/option_registry.rbs
112
+ - sig/mdlogbook/overlap_checker.rbs
113
+ - sig/mdlogbook/parser.rbs
114
+ - sig/mdlogbook/period_spec.rbs
115
+ - sig/mdlogbook/raw_extractor.rbs
116
+ - sig/mdlogbook/runner.rbs
117
+ - sig/mdlogbook/runner/base.rbs
118
+ - sig/mdlogbook/runner/editor_runner.rbs
119
+ - sig/mdlogbook/runner/extract_format_runner.rbs
120
+ - sig/mdlogbook/runner/standard_format_runner.rbs
121
+ - sig/mdlogbook/runner/visual_format_runner.rbs
122
+ - sig/mdlogbook/section_extractor.rbs
123
+ - sig/mdlogbook/work_thresholds.rbs
124
+ homepage: https://github.com/arika/mdlogbook
125
+ licenses:
126
+ - MIT
127
+ metadata:
128
+ allowed_push_host: https://rubygems.org
129
+ homepage_uri: https://github.com/arika/mdlogbook
130
+ source_code_uri: https://github.com/arika/mdlogbook
131
+ changelog_uri: https://github.com/arika/mdlogbook/blob/main/CHANGELOG.md
132
+ rdoc_options: []
133
+ require_paths:
134
+ - lib
135
+ required_ruby_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: 3.3.0
140
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ requirements: []
146
+ rubygems_version: 4.0.6
147
+ specification_version: 4
148
+ summary: CLI tool to aggregate work hours from Markdown logbooks
149
+ test_files: []