calendario 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9291a462c911bf262155797e6e486d8732c9b5e71072e62786400f8fe2a9255c
4
+ data.tar.gz: a97194dcf9e9a4d26e5cf8dd549980da27d614a5056eec1c3dec5f133c29b768
5
+ SHA512:
6
+ metadata.gz: 7bd0eae6c396824afcb80847c5fce30fbf7f05b4cc209376c855450cd453b12234060ef0efb241122f4a738830696731a45da4d686852ad5c2b72150a8b5d49a
7
+ data.tar.gz: 436d795f293c0ec6fdcc08218e9826a8d1f725ebb6dcae03b94963aded5dcff0d3c76e688a9d84641d6f4b0f0303b1fb0e843c9d24bb261bdfc562dce0d375e3
@@ -0,0 +1,14 @@
1
+ # Unix-style newlines with a newline ending every file
2
+ [*]
3
+ end_of_line = lf
4
+ insert_final_newline = true
5
+ max_line_length = 120
6
+ trim_trailing_whitespace = true
7
+
8
+ [*.snap]
9
+ trim_trailing_whitespace = false
10
+
11
+ # 2 space indentation
12
+ [*.rb]
13
+ indent_style = space
14
+ indent_size = 2
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /.yardocck
5
+ /coverage/
6
+ /doc/
7
+ /Gemfile.lock
8
+ /measurements/
9
+ /pkg/
10
+ /spec/reports/
11
+ /tmp/
12
+
13
+ # rspec failure tracking
14
+ .rspec_status
@@ -0,0 +1,31 @@
1
+ # Use this file to configure the Overcommit hooks you wish to use. This will
2
+ # extend the default configuration defined in:
3
+ # https://github.com/sds/overcommit/blob/master/config/default.yml
4
+ #
5
+ # At the topmost level of this YAML file is a key representing type of hook
6
+ # being run (e.g. pre-commit, commit-msg, etc.). Within each type you can
7
+ # customize each hook, such as whether to only run it on certain files (via
8
+ # `include`), whether to only display output if it fails (via `quiet`), etc.
9
+ #
10
+ # For a complete list of hooks, see:
11
+ # https://github.com/sds/overcommit/tree/master/lib/overcommit/hook
12
+ #
13
+ # For a complete list of options that you can use to customize hooks, see:
14
+ # https://github.com/sds/overcommit#configuration
15
+ #
16
+ # Uncomment the following lines to make the configuration take effect.
17
+
18
+ PreCommit:
19
+ RuboCop:
20
+ enabled: true
21
+ on_warn: fail # Treat all warnings as failures
22
+
23
+ TrailingWhitespace:
24
+ enabled: true
25
+
26
+ #PostCheckout:
27
+ # ALL: # Special hook name that customizes all hooks of this type
28
+ # quiet: true # Change all post-checkout hooks to only display output on failure
29
+ #
30
+ # IndexTags:
31
+ # enabled: true # Generate a tags file with `ctags` each time HEAD changes
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,27 @@
1
+ require: rubocop-rspec
2
+
3
+ AllCops:
4
+ DisplayCopNames: true
5
+ NewCops: enable
6
+
7
+ # ----------------------- Layout ----------------------
8
+
9
+ Layout:
10
+ Max: 120
11
+
12
+ # ---------------------- Metrics ----------------------
13
+
14
+ Metrics/BlockLength:
15
+ Exclude:
16
+ - '**/*_spec.rb'
17
+ - calendario.gemspec
18
+
19
+ # ----------------------- RSpec -----------------------
20
+
21
+ RSpec/ExampleLength:
22
+ Enabled: false
23
+
24
+ # ----------------------- Style -----------------------
25
+
26
+ Style/FrozenStringLiteralComment:
27
+ Enabled: false
@@ -0,0 +1 @@
1
+ ruby 2.7.1
@@ -0,0 +1,25 @@
1
+ ---
2
+ language: ruby
3
+ cache: bundler
4
+
5
+ rvm:
6
+ - 2.5
7
+ - 2.6
8
+ - 2.7
9
+ - jruby
10
+
11
+ before_install: gem install bundler -v 2.1.4
12
+
13
+ before_script:
14
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
15
+ - chmod +x ./cc-test-reporter
16
+ - ./cc-test-reporter before-build
17
+
18
+ script:
19
+ - bundle exec bundle-audit
20
+ - bundle exec rspec
21
+ - bundle exec rubocop
22
+ - bundle exec rake yard:junk
23
+
24
+ after_script:
25
+ - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
@@ -0,0 +1,22 @@
1
+ threshold: 100
2
+ rules:
3
+ ApiTag::Presence:
4
+ enabled: true
5
+ ApiTag::Inclusion:
6
+ enabled: true
7
+ ApiTag::ProtectedMethod:
8
+ enabled: true
9
+ ApiTag::PrivateMethod:
10
+ enabled: true
11
+ ExampleTag:
12
+ enabled: true
13
+ ReturnTag:
14
+ enabled: true
15
+ Summary::Presence:
16
+ enabled: true
17
+ Summary::Length:
18
+ enabled: false
19
+ Summary::Delimiter:
20
+ enabled: true
21
+ Summary::SingleLine:
22
+ enabled: false
@@ -0,0 +1,12 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
+ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [0.1.0] - 2020-06-25
8
+ ### Added
9
+ - Initial core functionality
10
+ - Codebase maintenance tools
11
+
12
+ [0.1.0]: https://github.com/wilsonsilva/tuga/compare/15adab8...v0.1.0
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at wilson.dsigns@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [https://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: https://contributor-covenant.org
74
+ [version]: https://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in calendario.gemspec
4
+ gemspec
@@ -0,0 +1,20 @@
1
+ guard :bundler do
2
+ watch('calendario.gemspec')
3
+ end
4
+
5
+ guard :bundler_audit, run_on_start: true do
6
+ watch('Gemfile.lock')
7
+ end
8
+
9
+ group :tests do
10
+ guard :rspec, all_on_start: true, cmd: 'COVERAGE=false bundle exec rspec --format progress' do
11
+ watch(%r{^spec/.+_spec\.rb$})
12
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
13
+ watch('spec/spec_helper.rb') { 'spec' }
14
+ end
15
+ end
16
+
17
+ guard :rubocop do
18
+ watch(/.+\.rb$/)
19
+ watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
20
+ end
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Wilson Silva
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,122 @@
1
+ # Calendario
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/caendario.svg)](https://badge.fury.io/rb/caendario)
4
+ [![Build Status](https://travis-ci.org/wilsonsilva/caendario.svg?branch=master)](https://travis-ci.org/wilsonsilva/caendario)
5
+ [![Maintainability](https://api.codeclimate.com/v1/badges/7afec90a09db3956b7dc/maintainability)](https://codeclimate.com/github/wilsonsilva/caendario/maintainability)
6
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/7afec90a09db3956b7dc/test_coverage)](https://codeclimate.com/github/wilsonsilva/caendario/test_coverage)
7
+ [![Security](https://hakiri.io/github/wilsonsilva/caendario/master.svg)](https://hakiri.io/github/wilsonsilva/caendario/master)
8
+ [![Inline docs](http://inch-ci.org/github/wilsonsilva/caendario.svg?branch=master)](http://inch-ci.org/github/wilsonsilva/caendario)
9
+
10
+ A cal-like calendar.
11
+
12
+ ```shell script
13
+ 2020
14
+ January February March
15
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
16
+ 1 2 3 4 1 1 2 3 4 5 6 7
17
+ 5 6 7 8 9 10 11 2 3 4 5 6 7 8 8 9 10 11 12 13 14
18
+ 12 13 14 15 16 17 18 9 10 11 12 13 14 15 15 16 17 18 19 20 21
19
+ 19 20 21 22 23 24 25 16 17 18 19 20 21 22 22 23 24 25 26 27 28
20
+ 26 27 28 29 30 31 23 24 25 26 27 28 29 29 30 31
21
+
22
+
23
+ April May June
24
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
25
+ 1 2 3 4 1 2 1 2 3 4 5 6
26
+ 5 6 7 8 9 10 11 3 4 5 6 7 8 9 7 8 9 10 11 12 13
27
+ 12 13 14 15 16 17 18 10 11 12 13 14 15 16 14 15 16 17 18 19 20
28
+ 19 20 21 22 23 24 25 17 18 19 20 21 22 23 21 22 23 24 25 26 27
29
+ 26 27 28 29 30 24 25 26 27 28 29 30 28 29 30
30
+ 31
31
+
32
+ July August September
33
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
34
+ 1 2 3 4 1 1 2 3 4 5
35
+ 5 6 7 8 9 10 11 2 3 4 5 6 7 8 6 7 8 9 10 11 12
36
+ 12 13 14 15 16 17 18 9 10 11 12 13 14 15 13 14 15 16 17 18 19
37
+ 19 20 21 22 23 24 25 16 17 18 19 20 21 22 20 21 22 23 24 25 26
38
+ 26 27 28 29 30 31 23 24 25 26 27 28 29 27 28 29 30
39
+ 30 31
40
+
41
+ October November December
42
+ Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
43
+ 1 2 3 1 2 3 4 5 6 7 1 2 3 4 5
44
+ 4 5 6 7 8 9 10 8 9 10 11 12 13 14 6 7 8 9 10 11 12
45
+ 11 12 13 14 15 16 17 15 16 17 18 19 20 21 13 14 15 16 17 18 19
46
+ 18 19 20 21 22 23 24 22 23 24 25 26 27 28 20 21 22 23 24 25 26
47
+ 25 26 27 28 29 30 31 29 30 27 28 29 30 31
48
+ ```
49
+
50
+ ## Installation
51
+
52
+ Add this line to your application's Gemfile:
53
+
54
+ ```ruby
55
+ gem 'calendario'
56
+ ```
57
+
58
+ And then execute:
59
+
60
+ $ bundle install
61
+
62
+ Or install it yourself as:
63
+
64
+ $ gem install calendario
65
+
66
+ ## Usage
67
+
68
+ Rendering the current year:
69
+ ```ruby
70
+ calendar = Calendario::Calendar.new
71
+ puts calendar.render_current_year
72
+ ```
73
+
74
+ You can also customize what to display on each day. For example, this code wil display the letters WE on weekends:
75
+ ```ruby
76
+ calendar = Calendario::Calendar.new
77
+ rendered_calendar = calendar.render_current_year do |date|
78
+ if date.wday == 5 || if date.wday == 6
79
+ 'WE'
80
+ else
81
+ date.day.to_s.rjust(2)
82
+ end
83
+ end
84
+
85
+ puts rendered_calendar
86
+ ```
87
+
88
+ ## Development
89
+
90
+ After checking out the repo, run `bin/setup` to install dependencies, configure git hooks and create support files.
91
+
92
+ You can also run `bin/console` for an interactive prompt that will allow you to experiment.
93
+
94
+ The health and maintainability of the codebase is ensured through a set of
95
+ Rake tasks to test, lint and audit the gem for security vulnerabilities and documentation:
96
+
97
+ ```
98
+ rake bundle:audit # Checks for vulnerable versions of gems
99
+ rake qa # Test, lint and perform security and documentation audits
100
+ rake rubocop # Lint the codebase with RuboCop
101
+ rake rubocop:auto_correct # Auto-correct RuboCop offenses
102
+ rake spec # Run RSpec code examples
103
+ rake verify_measurements # Verify that yardstick coverage is at least 100%
104
+ rake yard # Generate YARD Documentation
105
+ rake yard:junk # Check the junk in your YARD Documentation
106
+ rake yardstick_measure # Measure docs in lib/**/*.rb with yardstick
107
+ ```
108
+
109
+ ## Contributing
110
+
111
+ Bug reports and pull requests are welcome on GitHub at https://github.com/wilsonsilva/calendario. This project is
112
+ intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the
113
+ [code of conduct](https://github.com/wilsonsilva/calendario/blob/master/CODE_OF_CONDUCT.md).
114
+
115
+ ## License
116
+
117
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
118
+
119
+ ## Code of Conduct
120
+
121
+ Everyone interacting in the Calendario project's codebases, issue trackers, chat rooms and mailing lists is expected
122
+ to follow the [code of conduct](https://github.com/wilsonsilva/calendario/blob/master/CODE_OF_CONDUCT.md).
@@ -0,0 +1,7 @@
1
+ # Roadmap
2
+
3
+ - [ ] Support the formatting of different kinds of time periods (not just years)
4
+ - [ ] Add more time period formats (horizontal, different columns)
5
+ - [ ] Add a CLI and make it behave a little like Unix's `cal`
6
+ - [ ] Support different calendar types (Julian, etc)
7
+ - [ ] Support for themes, perhaps with a plugin extension `calendario-themes` that depends on the `pastel` gem
@@ -0,0 +1,37 @@
1
+ require 'bundler/audit/task'
2
+ require 'bundler/gem_tasks'
3
+ require 'rspec/core/rake_task'
4
+ require 'rubocop/rake_task'
5
+ require 'yaml'
6
+ require 'yard/rake/yardoc_task'
7
+ require 'yard-junk/rake'
8
+ require 'yardstick/rake/measurement'
9
+ require 'yardstick/rake/verify'
10
+
11
+ yardstick_options = YAML.load_file('.yardstick.yml')
12
+
13
+ Bundler::Audit::Task.new
14
+ RSpec::Core::RakeTask.new(:spec)
15
+ RuboCop::RakeTask.new
16
+ YARD::Rake::YardocTask.new
17
+ YardJunk::Rake.define_task
18
+ Yardstick::Rake::Measurement.new(:yardstick_measure, yardstick_options)
19
+ Yardstick::Rake::Verify.new
20
+
21
+ task default: :spec
22
+
23
+ # Remove the report on rake clobber
24
+ CLEAN.include('measurements', 'doc', '.yardoc', 'tmp')
25
+
26
+ # Delete these files and folders when running rake clobber.
27
+ CLOBBER.include('coverage', '.rspec_status')
28
+
29
+ desc 'Run spec with coverage'
30
+ task :coverage do
31
+ ENV['COVERAGE'] = 'true'
32
+ Rake::Task['spec'].execute
33
+ `open coverage/index.html`
34
+ end
35
+
36
+ desc 'Test, lint and perform security and documentation audits'
37
+ task qa: %w[spec rubocop yard:junk verify_measurements bundle:audit]
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'calendario'
5
+ require 'pry'
6
+
7
+ Pry.start
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ if ! which overcommit >/dev/null; then
9
+ echo 'The gem overcommit is not installed. It is necessary to lint the git history through git hooks.'
10
+ echo 'Please install overcommit and run this script again.'
11
+ exit 1
12
+ fi
13
+
14
+ overcommit --install
@@ -0,0 +1,48 @@
1
+ require_relative 'lib/calendario/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = 'calendario'
5
+ spec.version = Calendario::VERSION
6
+ spec.authors = ['Wilson Silva']
7
+ spec.email = ['me@wilsonsilva.net']
8
+
9
+ spec.summary = 'A cal-like calendar'
10
+ spec.description = 'A cal-like calendar'
11
+ spec.homepage = 'https://github.com/wilsonsilva/calendario'
12
+ spec.license = 'MIT'
13
+
14
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0')
15
+
16
+ spec.metadata['homepage_uri'] = spec.homepage
17
+ spec.metadata['source_code_uri'] = 'https://github.com/wilsonsilva/calendario'
18
+ spec.metadata['changelog_uri'] = 'https://github.com/wilsonsilva/calendario/blob/master/CHANGELOG.md'
19
+
20
+ # Specify which files should be added to the gem when it is released.
21
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
23
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
+ end
25
+
26
+ spec.bindir = 'exe'
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ['lib']
29
+
30
+ spec.add_development_dependency 'bundler-audit', '~> 0.7'
31
+ spec.add_development_dependency 'guard', '~> 2.16'
32
+ spec.add_development_dependency 'guard-bundler', '~> 3.0'
33
+ spec.add_development_dependency 'guard-bundler-audit', '~> 0.1'
34
+ spec.add_development_dependency 'guard-rspec', '~> 4.7'
35
+ spec.add_development_dependency 'guard-rubocop', '~> 1.3'
36
+ spec.add_development_dependency 'memoria', '~> 0.1'
37
+ spec.add_development_dependency 'overcommit', '~> 0.53'
38
+ spec.add_development_dependency 'pry', '~> 0.13'
39
+ spec.add_development_dependency 'rake', '~> 13.0'
40
+ spec.add_development_dependency 'rspec', '~> 3.0'
41
+ spec.add_development_dependency 'rubocop', '~> 0.85'
42
+ spec.add_development_dependency 'rubocop-rspec', '~> 1.40'
43
+ spec.add_development_dependency 'simplecov', '~> 0.17.1'
44
+ spec.add_development_dependency 'simplecov-console', '~> 0.7'
45
+ spec.add_development_dependency 'yard', '~> 0.9'
46
+ spec.add_development_dependency 'yard-junk', '~> 0.0.7'
47
+ spec.add_development_dependency 'yardstick', '~> 0.9'
48
+ end
@@ -0,0 +1,6 @@
1
+ require 'calendario/calendar'
2
+ require 'calendario/version'
3
+
4
+ # Encapsulates all the calendar logic
5
+ module Calendario
6
+ end
@@ -0,0 +1,49 @@
1
+ require 'calendario/renderers/year_renderer'
2
+ require 'calendario/year'
3
+
4
+ module Calendario
5
+ # A time period to be rendered
6
+ class Calendar
7
+ # Formats a year, line by line, in a table of 3 columns by 4 rows
8
+ #
9
+ # @api private
10
+ # @return [Calendario::Renderers::YearRenderer]
11
+ #
12
+ attr_reader :year_renderer
13
+
14
+ # Initialize a calendar
15
+ #
16
+ # @api private
17
+ # @param [Calendario::Renderers::YearRenderer] year_renderer # Formats a year, line by line, in a
18
+ # table of 3 columns by 4 rows
19
+ #
20
+ def initialize(year_renderer = Renderers::YearRenderer.new)
21
+ @year_renderer = year_renderer
22
+ end
23
+
24
+ # Renders the current year as a string
25
+ #
26
+ # @api public
27
+ #
28
+ # @example Rendering the current year
29
+ # calendar = Calendario::Calendar.new
30
+ # calendar.render_current_year
31
+ #
32
+ # @example Rendering a customized version of the current year
33
+ # calendar = Calendario::Calendar.new
34
+ # calendar.render_current_year do |date|
35
+ # if date.wday == 5 || if date.wday == 6
36
+ # 'WE'
37
+ # else
38
+ # date.day.to_s.rjust(2)
39
+ # end
40
+ # end
41
+ #
42
+ # @return [String]
43
+ #
44
+ def render_current_year(&block)
45
+ year = Year.new(Date.today.year)
46
+ year_renderer.render(year, &block)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,83 @@
1
+ require 'date'
2
+
3
+ module Calendario
4
+ # Any of the twelve parts, as January or February, into which the calendar year is divided
5
+ class Month
6
+ # List of month names (January, February, etc)
7
+ MONTH_NAMES = Date::MONTHNAMES.freeze
8
+
9
+ # The last day of the week is Saturday, in conformity with Ruby's standard library
10
+ LAST_DAY_OF_THE_WEEK = 'Saturday'.freeze
11
+
12
+ # Array of 28 to 31 days, depending on the month
13
+ #
14
+ # @api private
15
+ # @return [Array<Date>]
16
+ #
17
+ attr_reader :days
18
+
19
+ # The month's number from 1 to 12
20
+ #
21
+ # @api private
22
+ # @return [Integer]
23
+ #
24
+ attr_reader :month_number
25
+
26
+ # The primitive numeric representation of a year
27
+ #
28
+ # @api private
29
+ # @return [Integer]
30
+ #
31
+ attr_reader :year_number
32
+
33
+ # Initialize a month
34
+ #
35
+ # @api private
36
+ # @param [Integer] year_number The primitive numeric representation of a year
37
+ # @param [Integer] month_number The month's number from 1 to 12
38
+ #
39
+ def initialize(year_number = 2020, month_number = 1)
40
+ @year_number = year_number
41
+ @month_number = month_number
42
+ @days = (first_day..last_day).to_a
43
+ end
44
+
45
+ # First day of the month
46
+ #
47
+ # @api private
48
+ # @return [Date]
49
+ #
50
+ def first_day
51
+ @first_day ||= Date.new(year_number, month_number, 1)
52
+ end
53
+
54
+ # Last day of the month
55
+ #
56
+ # @api private
57
+ # @return [Date]
58
+ #
59
+ def last_day
60
+ @last_day ||= Date.new(year_number, month_number, -1)
61
+ end
62
+
63
+ # Array of weeks in the month. Weeks start on Sunday and end on Saturday
64
+ #
65
+ # @api private
66
+ # @return [Array<Date>]
67
+ #
68
+ def weeks
69
+ @weeks ||= days.slice_when do |day|
70
+ Date::DAYNAMES[day.wday] == LAST_DAY_OF_THE_WEEK
71
+ end.to_a
72
+ end
73
+
74
+ # Full name of the month (ex: January)
75
+ #
76
+ # @api private
77
+ # @return [String]
78
+ #
79
+ def name
80
+ MONTH_NAMES[month_number]
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,148 @@
1
+ require 'calendario/month'
2
+
3
+ module Calendario
4
+ module Renderers
5
+ # Formats a year, line by line, in a table of 3 columns by 4 rows
6
+ class YearRenderer
7
+ # The space of an empty day (3 = 2 digits + 1 space between digits)
8
+ EMPTY_DAY_SPACES = ' ' * 3
9
+
10
+ # The space to add on the 6th row of a month when that row is empty
11
+ EMPTY_WEEK_SPACES = ' ' * 20
12
+
13
+ # Formats a year, line by line, in a table of 3 columns by 4 rows like this:
14
+ #
15
+ # 2020 | Title, centered
16
+ # January February March | Names of months, centered
17
+ # Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa | Weekday initials
18
+ # 1 2 3 4 1 1 2 3 4 5 6 7 | Rows of weeks
19
+ # 5 6 7 8 9 10 11 2 3 4 5 6 7 8 8 9 10 11 12 13 14 |
20
+ # 12 13 14 15 16 17 18 9 10 11 12 13 14 15 15 16 17 18 19 20 21 |
21
+ # 19 20 21 22 23 24 25 16 17 18 19 20 21 22 22 23 24 25 26 27 28 |
22
+ # 26 27 28 29 30 31 23 24 25 26 27 28 29 29 30 31 | Add spaces after the last day of the
23
+ # | month until the first day of the week of
24
+ # | the month of the following month on the
25
+ # April May June | same row.
26
+ # Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa |
27
+ # 1 2 3 4 1 2 1 2 3 4 5 6 | Add spaces before the first day of the
28
+ # 5 6 7 8 9 10 11 3 4 5 6 7 8 9 7 8 9 10 11 12 13 | month unless it is a Sunday.
29
+ # 12 13 14 15 16 17 18 10 11 12 13 14 15 16 14 15 16 17 18 19 20 |
30
+ # 19 20 21 22 23 24 25 17 18 19 20 21 22 23 21 22 23 24 25 26 27 |
31
+ # 26 27 28 29 30 24 25 26 27 28 29 30 28 29 30 |
32
+ # 31 | Add spaces before a day on the second
33
+ # | or third month columns if the first or
34
+ # July August September | second columns month are empty.
35
+ # Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa |
36
+ # 1 2 3 4 1 1 2 3 4 5 |
37
+ # 5 6 7 8 9 10 11 2 3 4 5 6 7 8 6 7 8 9 10 11 12 |
38
+ # 12 13 14 15 16 17 18 9 10 11 12 13 14 15 13 14 15 16 17 18 19 |
39
+ # 19 20 21 22 23 24 25 16 17 18 19 20 21 22 20 21 22 23 24 25 26 |
40
+ # 26 27 28 29 30 31 23 24 25 26 27 28 29 27 28 29 30 |
41
+ # 30 31 |
42
+ # |
43
+ # October November December |
44
+ # Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa |
45
+ # 1 2 3 1 2 3 4 5 6 7 1 2 3 4 5 |
46
+ # 4 5 6 7 8 9 10 8 9 10 11 12 13 14 6 7 8 9 10 11 12 |
47
+ # 11 12 13 14 15 16 17 15 16 17 18 19 20 21 13 14 15 16 17 18 19 |
48
+ # 18 19 20 21 22 23 24 22 23 24 25 26 27 28 20 21 22 23 24 25 26 |
49
+ # 25 26 27 28 29 30 31 29 30 27 28 29 30 31 |
50
+ #
51
+ # @api private
52
+ # @param [Year] year The year to be formatted.
53
+ # @return [String]
54
+ #
55
+ def render(year)
56
+ output = centered_year_line(year)
57
+
58
+ # Display months in
59
+ year.months.each_slice(3).with_index do |group_of_3_months, month_row|
60
+ output << month_names_line(group_of_3_months)
61
+ output << weekdays_initials_line
62
+
63
+ # Display 6 rows of days. Each row is a week.
64
+ 0.upto(5) do |week_number|
65
+ # Display
66
+ group_of_3_months.each_with_index do |month, index|
67
+ # Correct the position for the first date of the first week
68
+ output << EMPTY_DAY_SPACES * month.first_day.wday if week_number.zero?
69
+
70
+ # Display a complete row of week days
71
+ output << (month.weeks[week_number] || []).map do |date|
72
+ if block_given?
73
+ yield(date)
74
+ else
75
+ date.day.to_s.rjust(2)
76
+ end
77
+ end.join(' ') + ' '
78
+
79
+ # Correct the position for the first date of the following month
80
+ output << lead_space_after_last_day(month) if last_week_of_the_month?(month, week_number)
81
+
82
+ # Correct the position of the dates on empty rows (usually the last week)
83
+ output << EMPTY_WEEK_SPACES if week_number == 5 && group_of_3_months[index - 1].weeks[week_number].nil?
84
+ end
85
+
86
+ # End of the week row. Start the next one on the next line
87
+ output << "\n"
88
+ end
89
+
90
+ # Separate rows of months
91
+ output << "\n" if month_row < 3
92
+ end
93
+
94
+ output
95
+ end
96
+
97
+ private
98
+
99
+ # Adds blank spaces to fill the empty week days on the last week row of the month
100
+ #
101
+ # @api private
102
+ # @param [Month] month
103
+ # @return [String]
104
+ #
105
+ def lead_space_after_last_day(month)
106
+ EMPTY_DAY_SPACES * (6 - month.last_day.wday)
107
+ end
108
+
109
+ # Centers the year in the middle of the calendar
110
+ #
111
+ # @api private
112
+ # @param [Year] year The year to be displayed at the top of the calendar
113
+ # @return [String]
114
+ #
115
+ def centered_year_line(year)
116
+ year.year_number.to_s.center(61) + "\n"
117
+ end
118
+
119
+ # Displays 3 columns of month names in a line
120
+ #
121
+ # @api private
122
+ # @param [Array<Month>] group_of_3_months The list of months whose names will be displayed
123
+ # @return [String]
124
+ #
125
+ def month_names_line(group_of_3_months)
126
+ group_of_3_months.map { |month| month.name.center(20) }.join(' ') + " \n"
127
+ end
128
+
129
+ # Displays 3 columns of weekdays initials in a line
130
+ #
131
+ # @api private
132
+ # @return [String]
133
+ #
134
+ def weekdays_initials_line
135
+ "Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa \n"
136
+ end
137
+
138
+ # Whether the week is the last week of the month
139
+ #
140
+ # @api private
141
+ # @return [Boolean]
142
+ #
143
+ def last_week_of_the_month?(month, week_number)
144
+ month.weeks[week_number] == month.weeks.last
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,3 @@
1
+ module Calendario
2
+ VERSION = '0.1.0'.freeze
3
+ end
@@ -0,0 +1,60 @@
1
+ require 'calendario/month'
2
+ require 'date'
3
+
4
+ module Calendario
5
+ # A period of 365 or 366 days, in the Gregorian calendar, divided into 12 calendar months
6
+ class Year
7
+ # Array of all calendar months
8
+ #
9
+ # @api private
10
+ # @return [Array<Month>]
11
+ #
12
+ attr_reader :months
13
+
14
+ # The primitive numeric representation of a year
15
+ #
16
+ # @api private
17
+ # @return [Integer]
18
+ #
19
+ attr_reader :year_number
20
+
21
+ # Initialize a year
22
+ #
23
+ # @api private
24
+ # @param [Integer] year_number The primitive numeric representation of a year
25
+ #
26
+ def initialize(year_number = 2020)
27
+ @year_number = year_number
28
+ @months = 1.upto(12).map do |month_number|
29
+ Month.new(year_number, month_number)
30
+ end
31
+ end
32
+
33
+ # The first day of the year (1st of January)
34
+ #
35
+ # @api private
36
+ # @return [Date]
37
+ #
38
+ def first_day
39
+ @first_day ||= months.first.first_day
40
+ end
41
+
42
+ # The last day of the year (31st of December)
43
+ #
44
+ # @api private
45
+ # @return [Date]
46
+ #
47
+ def last_day
48
+ @last_day ||= months.last.last_day
49
+ end
50
+
51
+ # An array of 365 or 365 dates representing every day of the year
52
+ #
53
+ # @api private
54
+ # @return [Date]
55
+ #
56
+ def days
57
+ @days ||= months.map(&:days).flatten
58
+ end
59
+ end
60
+ end
metadata ADDED
@@ -0,0 +1,323 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: calendario
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Wilson Silva
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-06-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler-audit
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: guard
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.16'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.16'
41
+ - !ruby/object:Gem::Dependency
42
+ name: guard-bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: guard-bundler-audit
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.1'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: guard-rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '4.7'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '4.7'
83
+ - !ruby/object:Gem::Dependency
84
+ name: guard-rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.3'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.3'
97
+ - !ruby/object:Gem::Dependency
98
+ name: memoria
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.1'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.1'
111
+ - !ruby/object:Gem::Dependency
112
+ name: overcommit
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0.53'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '0.53'
125
+ - !ruby/object:Gem::Dependency
126
+ name: pry
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.13'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.13'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rake
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '13.0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '13.0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rspec
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '3.0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '3.0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: rubocop
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '0.85'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '0.85'
181
+ - !ruby/object:Gem::Dependency
182
+ name: rubocop-rspec
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '1.40'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: '1.40'
195
+ - !ruby/object:Gem::Dependency
196
+ name: simplecov
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: 0.17.1
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: 0.17.1
209
+ - !ruby/object:Gem::Dependency
210
+ name: simplecov-console
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - "~>"
214
+ - !ruby/object:Gem::Version
215
+ version: '0.7'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - "~>"
221
+ - !ruby/object:Gem::Version
222
+ version: '0.7'
223
+ - !ruby/object:Gem::Dependency
224
+ name: yard
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - "~>"
228
+ - !ruby/object:Gem::Version
229
+ version: '0.9'
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - "~>"
235
+ - !ruby/object:Gem::Version
236
+ version: '0.9'
237
+ - !ruby/object:Gem::Dependency
238
+ name: yard-junk
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - "~>"
242
+ - !ruby/object:Gem::Version
243
+ version: 0.0.7
244
+ type: :development
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - "~>"
249
+ - !ruby/object:Gem::Version
250
+ version: 0.0.7
251
+ - !ruby/object:Gem::Dependency
252
+ name: yardstick
253
+ requirement: !ruby/object:Gem::Requirement
254
+ requirements:
255
+ - - "~>"
256
+ - !ruby/object:Gem::Version
257
+ version: '0.9'
258
+ type: :development
259
+ prerelease: false
260
+ version_requirements: !ruby/object:Gem::Requirement
261
+ requirements:
262
+ - - "~>"
263
+ - !ruby/object:Gem::Version
264
+ version: '0.9'
265
+ description: A cal-like calendar
266
+ email:
267
+ - me@wilsonsilva.net
268
+ executables: []
269
+ extensions: []
270
+ extra_rdoc_files: []
271
+ files:
272
+ - ".editorconfig"
273
+ - ".gitignore"
274
+ - ".overcommit.yml"
275
+ - ".rspec"
276
+ - ".rubocop.yml"
277
+ - ".tool-versions"
278
+ - ".travis.yml"
279
+ - ".yardstick.yml"
280
+ - CHANGELOG.md
281
+ - CODE_OF_CONDUCT.md
282
+ - Gemfile
283
+ - Guardfile
284
+ - LICENSE.txt
285
+ - README.md
286
+ - ROADMAP.md
287
+ - Rakefile
288
+ - bin/console
289
+ - bin/setup
290
+ - calendario.gemspec
291
+ - lib/calendario.rb
292
+ - lib/calendario/calendar.rb
293
+ - lib/calendario/month.rb
294
+ - lib/calendario/renderers/year_renderer.rb
295
+ - lib/calendario/version.rb
296
+ - lib/calendario/year.rb
297
+ homepage: https://github.com/wilsonsilva/calendario
298
+ licenses:
299
+ - MIT
300
+ metadata:
301
+ homepage_uri: https://github.com/wilsonsilva/calendario
302
+ source_code_uri: https://github.com/wilsonsilva/calendario
303
+ changelog_uri: https://github.com/wilsonsilva/calendario/blob/master/CHANGELOG.md
304
+ post_install_message:
305
+ rdoc_options: []
306
+ require_paths:
307
+ - lib
308
+ required_ruby_version: !ruby/object:Gem::Requirement
309
+ requirements:
310
+ - - ">="
311
+ - !ruby/object:Gem::Version
312
+ version: 2.3.0
313
+ required_rubygems_version: !ruby/object:Gem::Requirement
314
+ requirements:
315
+ - - ">="
316
+ - !ruby/object:Gem::Version
317
+ version: '0'
318
+ requirements: []
319
+ rubygems_version: 3.1.2
320
+ signing_key:
321
+ specification_version: 4
322
+ summary: A cal-like calendar
323
+ test_files: []